知识卡片

最大Commit原则:为什么恢复时每条日志都要重新执行完整Paxos

普通读书笔记卡

内容

把[[Paxos两阶段协议的核心机制:Prepare的”两个承诺一个应答”与Accept达成决议]]应用到日志同步场景,理论模型是把每条日志看作一个独立的Paxos Instance,用连续递增的LogID标识,多个客户端可以并发地向集群任意机器发送日志同步请求,每条日志各自独立跑完整的两阶段协议。但这个模型在实际运行中会出现一类看似矛盾的场景:假设A、B、C三台机器,一条日志在A、B上都已经持久化成功、已经形成了多数派,随后B宕机;另一种情况是这条日志只在A上持久化成功、还没形成多数派,随后B也宕机——这两种情况最终留下的物理状态是一样的(A上有这条日志、C上没有),但它们背后的真实语义完全不同:前者这条日志已经是正式决议、理应被保留和回放;后者这条日志根本没有真正达成一致,理应被视为未完成。问题在于,仅凭”A上有、C上没有”这个表面状态,系统本身根本无法区分究竟是上述哪一种情况。这里引出了一个关键原则——最大Commit原则:只有重新完整地执行一遍Paxos协议,才能得到这条日志到底应不应该被确认为决议的确定结果,无法通过检查已有的持久化状态来间接推断。这正是为什么在故障恢复时,系统要按LogID递增的顺序,对每一条日志都重新执行一遍完整的Paxos协议、只有真正走完协议达成决议的日志才能被回放——这个”看似保守”的做法,实际上是唯一能在存在歧义状态时给出确定答案的方法,任何试图靠”猜测”或”启发式规则”来判断某条日志是否该被确认的做法,都无法保证正确性。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.10 架构师需要了解的Paxos原理、历程及实战"节,"2.10.3 Basic Paxos同步日志的理论模型"(源文件:_epub-src/OEBPS/Text/Chapter2_10_4.xhtml) - 结论依据:原文举例A/B/C三机的两种场景最终状态相同但语义不同,并说明"这里提一个名词——最大Commit原则……对于上面的问题,答案就是无论如何都要对这条日志重新执行Paxos。这也是为什么在恢复的时候,我们要对每条日志都执行Paxos的原因",直接支撑本卡片结论。 - 原始内容:这2种情况,最终的状态都是A上有这条日志,C上没有,那么应该怎么处理呢?……对于上面的问题,答案就是无论如何都要对这条日志重新执行Paxos。这也是为什么在恢复的时候,我们要对每条日志都执行Paxos的原因。