基于Fabric 1.0.0以后版本,目前fabric提供的共识算法有三种:solo,kafka和PBFT
- solo模式
用于开发测试的单点共识,不用介绍什么。 - kafka模式
其是一种支持多通道分区的集群时序服务,可以容忍部分节点失效(crash),但不能容忍恶意节点,其基于zookeeper进行Paxos算法选举,支持2f+1节点集群,f代表失效节点个数。即kafka可以容忍少于半数的共识节点失效。 - PBFT算法
其是以前版本的主流共识算法,也就是拜占庭共识算法。拜占庭算法支持(3f+1)的节点集群,f代表恶意节点的数量。恶意节点可能会做一些恶意伪造时序或者返回相反的错误的结果等,注意这里与上面失效的区别。
目前,Fabric的整体共识(Kafka)分为两个步骤:
- Step 1:信任
这部分很多文章也讲过了。就是向endorser节点发送背书请求,节点针对身份、签名和读写集的验证后,发现没问题,就视为正确的信息。
这部分在整个出块过程中,担任了针对tx发起人的信任或者合法性进行审核的作用,也就是为下一步(无法确认信息有效性)做了一个筛选,或者说信任处理。所以,第二步骤,可以默认获得的输入都是安全有效的(谁知道呢?)。 - Step 2:时序
这一部分就是我们所说的kafka共识,而其主要也是唯一的参与者就是orderer集群。orderer的核心作用就是将全局的tx(通过背书请求后的)作为输入,在集群内形成统一的、唯一的、确定的、经过排序的tx输出。
这里我们提到的tx,无论是以读写集还是tx本身存在,统一看做是tx。
这部分做的事情有几个核心的要点:
- 不能容忍作恶。也就是说,针对恶意的数据(或者说input)没有能力进行识别和处理。它能处理什么?看第二点
- 基于Zookeeper进行paxos算法。paxos算法保证在orderer集群中,最终能够形成一个有效的输出结果,能够容忍一定的失效节点。在换句话说,能够容忍的错误就是某一个(一些)orderer节点不能用了,无论是无法处理请求、宕机,还是掉电。超过半数orderer集群的信息就没办法保证一致性。
这之后就是我瞎说的,请勿相信,发上来就是想大家一起讨论。
今天偶然看了一眼CAP,其中有一句话:
这篇论文证明了两个非常有意思的理论,首先是在异步的网络模型中,所有的节点由于没有时钟仅仅能根据接收到的消息作出判断,这时完全不能同时保证一致性、可用性和分区容错性,每一个系统只能在这三种特性中选择两种。
说的是CAP论文中的观点。其中没有时钟这前提条件非常重要。也就是如果有全局时钟,每个节点的时钟误差绝对值都不超过在消息传递的时间最小单位。那么我们针对信息打上时间戳,每个节点什么时候接受,都能够针对这些消息进行排序,然后处理,并最终得到一个有效的结果。我们只需要关注网络内最新的消息的sender、content就可以。
拉回fabric,我们可以发现,其实orderer在的目的就是为所有的tx输入,提供了一个类似时序机制的模块。虽然client提交的tx,peer发起的endorsement都是并发的,无序的。但是,经过orderer的整合之后,会将其整理成一个有序的输出。这就是orderer的核心价值。peer在需要的时候从orderer中pull到的需要打包的tx序列(读写集)就是(maybe)确认后的执行的结果。然后在进行验证写入账本并在网络上传播。
那么,多个orderer和单个orderer的区别就是备份,提高系统可用性。防止单点宕机无法提供服务的情况。同时orderer节点的分离式部署以及维护是否能够在将来构想更多的共识算法的可能性也未可知。
不过,这么感觉这一步分离以及tx的两段式打包,感觉还是有那么点意思。
我一直对fabric提出的共识可插拔表示怀疑,特别想把这块搞清楚。不过这就得看源码了。进一步的源码分析,稍后再添加。
(未完待续)