Tendermint被设计成易于使用、易于理解,且性能优异,适用于广泛的分布式应用。
正文
分布式共识系统成为现代互联网基础设施中的一个关键组件,正助力于每一个主要的互联网应用。本章节内容介绍了必要的背景材料来理解和探讨这些系统。
复制状态机(Replicated State Machine)
最常见的用来研究和实施分布式共识(distributed consensus)的范例的是复制状态机的范例,其中,一个确定的状态机在数个进程(processes)之间被复制,这样不管部分进程是否失败,这些进程看上去像单个状态机。状态机有一些列输入驱动,这些输入被称作交易(transactions),每一个交易根据其是否有效,可能引起一个状态迁移并返回一个结果。更正式的,交易为数据库上的原子操作(atomic operation),意味着其要么完成要么根本就没有发生,不能返回一个中间状态( intermediate state)。状态交易逻辑(state transition logic)由状态机的状态转移函数决定,这个函数映射了一个交易和目前的状态到一个新的状态和一个返回值。状态转移函数有时也被称为应用逻辑(application logic)。
订购交易(order the transactions)并且将相应的交易日志( transaction log )复制到每一个进程是共识协议的责任。使用一个确定的(deterministic)状态转移函数意味着在给定同样的交易日志的情况下,每一个进程将计算出相同的结果。
复制状态机架构如图所示。
如图:一个复制状态机在多个机器之间复制了一个交易日志和结果状态。交易从客户端接受,运行了共识协议,在交易日志中订购(ordered),最后执行得到最新状态。在图中,每一个菱形代表了单个机器,其中,虚线代表机器间的通讯用来承载进行订购交易( ordering transactions)的共识协议。
Tendermint的目标是创建一个通用目的,高性能,安全和健壮的复制状态机。
不同时性(Asynchrony)
容错复制状态机(fault-tolerant replicated state machine)的目的是在对上层提供服务的时候,协调网络中的计算机的同步,不管是否存在故障节点。
保持同步意味着成功复制交易日志;提供一个有用的服务意味着在处理新交易的时候保持状态机的可用性。传统上系统的这些方面被各自成为安全性(safety)和可用性(liveness)。通俗地,安全性意味着没有任何坏的事情发生;可用性意味着好的事情最终发生。安全违规( violation of safety)意味着存在两个或者更多的有效的,竞争的交易日志。可用性违规(violating liveness )意味着一个无法响应的网络。
通过接受所有的交易可以很容易来满足可用性。通过不接受任何交易可以很容易来满足安全性。因此,状态机复制算法可以被看作在两者之间的一个平衡。一般地,进程在提交一个新的交易在之前,需要对来自于其他进程的信息设立一个阈值。在同步的环境中,我们对网络消息的最大延迟或者处理器时钟的最大速度作出假设,通过轮流坐庄来提议新的交易,进行大多数投票表决,如果提议者在同步假设的区间内并没有产生任何提议,则跳过(skip)提议者的这一回合。
在一个异步的环境中,没有关于网络延迟或者处理器速度的保证的假设,权衡将变得更为困难。事实上,所谓的FLP不可能性结果(FLP impossibility result)证明了在确定的异步进程(单个进程可能会崩溃)之间的分布式共识的不可能性。该证明意味着,因为进程可能失败,存在协议的有效执行,但进程恰好在某一时间崩溃这样就阻止了共识。因此,我们对共识没有任何保证。
一般地,协议中的同步是通过管理某些交易时用到的超时(timeouts)来进行的。在异步环境中,消息能够被任意延迟,依赖同步来确保安全性的话可能导致交易日志的分叉。依赖同步来保证系统的可用性能够引起共识的宕机,并且服务无法响应。前者通常被看作更为严重,因为调解冲突日志可能是一个令人生畏或者不可能的任务。
实际上,仅当消息延迟能够被良好的定义和控制的时候,同步解决方案才会被使用,例如在一架飞机上的控制器之间,或者利用同步的原子时钟的数据中心之间。因此,尽管存在很多高效的同步解决方案,计算机网络的一般化的不可靠性(general unreliability)太大以至于不能实际投入使用而不显著增加额外的成本。
根本上有两种途径来克服FLP不可能性结果。第一个是采用更强的同步假设-甚至相当弱的假设也是足够的,例如,那个唯一的最终崩溃的进程被怀疑崩溃了,正确的进程不受影响。一般地,这个方法利用leaders,其扮演了一个特别的协作的角色,并且在超时并被认为发生故障了以后可以被跳过。实际上,这样的领导选取机制成功运转起来很难。
第二种克服FLP的方法是使用非确定性的-包含随机化元素,这样达成共识的可能性接近为1。尽管第二种方法更智能并且某些高级加密技术近些年来取得了速度上的提高,依赖随机化的方法通常更慢。
广播和共识
为了让一个进程复制状态到其它进程上,它必须有基本通讯原语的权限来允许其传播或者传递信息。一个最有用的原语是可靠广播(reliable broadcast)。可靠广播(RBC)是一个广播原语满足如下特性,对消息m,有:
有效性(validity) - 如果一个正确的进程广播m,它最终成功传达了m
一致性(agreement) - 如果一个正确的进程成功传达了m,所有最终所有的进程成功传达m
完整性(integrity) - m只传递一次,并且是以广播的形式被发送者发送出去
本质上,可靠广播使得消息最终到达所有的进程一次。
另外,更有用的原语是原子广播( atomic broadcast(ABC)),其满足可靠广播(RBC)和另外的一个属性:
总的顺序(total order) - 如果正确的进程p和q分别传递出m和m',p传达m在m'之前,那么q传达m在m'之前
原子广播是一个可靠的广播,其中值(values)以相同的顺序被发送到每个机器上。注意到这实际上复制交易日志的问题。通俗地讲,该问题可以被称作共识,共识原语的标准定义满足以下条件:
终止性 - 每个正确的进程最终能做出决定
完整性 - 每个正确的进程最多只做出决定一次
一致性 - 如果一个进程做出了v1的决定, 并且另外一个进程做出了v2的决定,那么v1=v2
有效性 - 如果一个正确的进程做出了v的决定,至少一个进程提议了v
直观地,共识和原子广播看上去十分类似,主要的差异在于,原子广播本身作为一个协议是连续的,然而共识期望终止。这就是说,每一个可以精简为另一个。共识可以被精简为原子广播通过决定第一个原子广播的值。原子广播可以精简为共识,通过依次运行许多共识协议的实例,然而存在一些微妙的考量,特别是在处理拜占庭故障方面。
一个完整的参数空间的关于原子广播精简为共识的描述仍然是一个开放的研究话题。
历史上,尽管大多数用例实际上需要原子广播,采用的最为广泛的算法是称作Paxos的共识算法,在90年代介绍并且