上一节课我们学习了PoW(Proof-of-Work,工作量证明)共识算法,了解其来源和优缺点,这节课我们将学习PBFT算法,了解PBFT算法如何通过三阶段协议保证了系统能够在包含作恶节点的情况下达成共识。
第十三课 PoW共识算法
1. 背景
通常情况下,分布式系统由很多节点组成,系统的可靠性要求系统必须具备应付异常节点发送过来的不一致消息的能力。分布式的这个场景最早由 Lamport,Shostak 和 Pease 于1982年形象地描述为拜占庭将军问题,即多个拜占庭将军各自率领了小分队驻扎在敌方城市之外,他们需要对是否进攻敌军达成统一的作战计划,但是这些将军之间存在反叛者,他们可能会篡改、延迟或者丢弃其他将军的命令,迷惑其他可信将军。拜占庭将军问题就是要找到一个算法来保证可信将军之间能够达成一致的作战计划。
Lamport他们证明了对于拜占庭将军问题,系统中如果存在f个不可信节点,那么只有总节点数不少于3f+1才存在一个算法解决该问题。下面我们来简单地证明这个问题解的不可能性,假设系统中总共有3个节点,Commander是提议者,记为C,Lieutenant 1 和Lieutenant 2 是验证节点,记为 LT1 和 LT2。这三个节点中存在一个作恶节点,下面我们证明在存在一个作恶节点的情况下,无论是提议者还是验证节点,系统均无法达成统一的共识。
如图1-1所示,假设 C 是作恶节点,另外两个节点是可信节点。C 向节点LT1和LT2发送了相互矛盾的命令— 进攻和撤退,那么LT1在接收到C发送过来的进攻命令和LT2转发过来的命令撤退,那么它就无法确定是要进攻还是撤退。
图1-1 提议者是作恶节点
如图1-2所示,假设 LT2 是作恶节点,节点 C 和 LT1 是可信节点,C要求LT1和LT2进攻,但是LT2在转发C的命令给LT1的时候作假,告诉LT1它接收到C发过来的命令是撤退,那么LT1在就无法判断到底是要进攻还是撤退。
图1-2 Lieutenant 2 是作恶节点
从上述论证中我们可以直观地觉察到3个节点的情况下,即使只有一个作恶节点,也无法达成共识。但如果系统中多一个可信节点LT3,则LT1可以收到可信节点Commander发出的和LT3转发的进攻命令,即使LT2节点发出撤退命令,LT1也可以正确选择跟大多数节点一致的进攻命令,这样系统能达成共识。我们可以将这个结论进行推广,即对于存在f个作恶节点的分布式系统,当节点总数不超过3f的时候,是不存在一个可以达成共识的解的。
学者们陆续提出了解决该问题的拜占庭容错算法BFT,不是只能用于同步系统,就是性能太差,难以在生产环境中广泛运用。为了解决BFT的实际运用问题,MIT计算机实验室的Castro和Liskov于1999年在OSDI会议上提出了能够在异步网络环境中工作的PBFT算法,在借鉴分布式系统的状态机复制和quorum的基础上设计了三阶段协议来解决一致性问题,同时引入了优化项,算法的复杂度由原来的指数级降低为多项式级别。下面我们会讲解PBFT算法的模型、算法流程、优化,其中算法流程即三阶段协议是PBFT算法的核心算法流程,是我们的重点讲解对象。
2. PBFT算法模型
</