POS共识机制
POS权益证明(proof of stake)。这个解释为股权证明,2012年sunny king首次提出了POS概念,POS不需要大量算力来维持网络安全,通过钱包相应权重来获取奖励。所谓POS股权证明,通俗解释依据你持有的数字货币的数量和持有时间,根据这个两个要素发放一个利息,这里的银行存款的概念很相似。这里需要引入一个币龄的概念,币龄根据你持有的币乘以持有时间来计算,一旦你发现了一个POS的区块,那么你的币龄就被清空。当你被清空了365币龄,你将获得0.05个币的利息,那么计算公式就是:数字货币量*持有时间/365=利息。Pos机制鼓励每个人去打开客户端钱包,根据上面对POS的解释,打开客户端钱包里才可能发现区块,那么就会获得利息,当然现在POS2.0的机制(下文会解释2.0)里,必须在线运行客户端钱包,才会按照你的数字货币持有量和运行客户端钱包时间分发利息,不停的有在线客户端钱包运行,这也就保障了整个系统网络的健壮和系统运行的保障了。昨天刚好有个朋友来问,在比特币系统中万一比特币挖完了,那么算力大大降低了,是不是就可能出现51%算力集中攻击。这个问题如果在POS机制中,就要求攻击者需要拥有51%的货币量,试想下,51%的货币量被控制,这个难度和这个环境的不可靠,应该也不会吸引到太多的人了。再对比下比特币,有些人认为比特币是不会膨胀的一个货币体系,因为他的数量的是确定的,但是有没有想过一个钱包丢失的问题,要深究的话,比特币是一个货币紧缩体系,总数一定,但是会有不确定丢失。
这里说了POS的机制,那和比特币的POW机制相比,POS认为是一定程序上缩短了达成共识的时间,而且节省了资源,不像POW需要大量的算力。但是POS也有自己不可避免的缺点,单纯来说POW中,算力是基础,根据算力来决定你的话语权,但是控制算力目前来看,规模越大,越无法控制甚至垄断,相对来说比较公平。POS类似股票,持有货币量决定话语权,在一个公司内部,前期奋斗,后期可能作为决策者有大量的股份那就有决定权,数字货币环境不是单纯的一个公司那么简单,数字货币要求一个公正的环境,那么POS机制下,后来者明显处于了劣势,你前期持有币,那么你就可以不断的通过利息机制获得新币,这个过程对于先前就掌握了币的人不需要付出太多的成本,可以永久吃利息,那么这会造成一个买卖币的问题,掌握了一定数量币,而且一直增加,那么就没有太大的卖币的需求,而且你的话语权因为你掌握的币不会变,后来者不管如何努力,话语权还是处于劣势。技术角度来说,之前的文章中有对软分叉和硬分叉做过简单介绍,那么在POS机制中,一旦发生了硬分叉,这个问题就相当复杂了,因为持有货币的人在两条链上都有相同数量的货币,新的分叉也能获得利益,那么这个分叉就很大程序会被默许,这样的分叉一旦出现就会不断出现,整个系统就处于崩溃,缺乏约束健壮性。大多数都是采用POS+POW机制,例如点点币,黑币。
POS2.0:这里再说下黑币,黑币的机制被称为POS2.0(上文有提过),这个概念是前5000个区块,使用纯POW机制,5001到10000使用POS和POW混合机制、10001之后采用纯POS机制。这种模式在前期完成开采和分配,然后再进入POS模式。
POS机制仁者见仁智者见智。
DPOS:股份授权证明机制
这种机制采用投票的方式,由Bitshares提出,先解释下这个投票过程:每一个持有数字货币的人来进行投票,投票选举一组代表,假设这一组的数据是101个,然后这101个代表理解成为101个特权节点,101个节点权利完全相等,类似议会制度,选举委员。当然不是选出后永远都是这些节点成为特权节点,一旦在生成区块的时候未能生成(这里会有网络原因,节点宕机,恶意行为等原因),节点被除名,再次选举新节点来替代。除名选举在系统中时刻进行。
这种方式仔细考虑下,时刻运行选择和除名操作,这样保证了网络上所有可信任节点,整个网络更加民主,不需要网络中所有节点或者大部分节点确认,被选举出来的节点实时保证在线有效,那么就保证了系统正常运行,更重要的是,区块一直由这些选举节点在确认生成大大提高了确认的效率,缩减整个交易确认时间,这个在很大程序上改善了比特币网络中POW效率的问题。对比之前的POW和POS机制,这种方式在单一区块中可容纳更多交易,使其可接近目前中心化系统的处理效率,每个节点投票选举,然后特权节点生成区块,每个节点有选举权,这样不依赖算力和持有币数量的的约束。有兴趣的可以看下DPOS的白皮书:https://wenku.baidu.com/view/74034196ba0d4a7303763a48.html
DPOS背后的理性逻辑:
使权益所有者能够通过投票决定记账人
最大化权益所有者的红利
最小化保证网络安全的消耗
最小化网络运行成本
最大化网络的性能
DPOS本质上是把整个网络中权益分给每一个节点,从而实现去中心化的概念,现实中的投票机制可能会有缺陷,但是通过不停的选举和淘汰,保证网络中节点的高效率,从而提高整个系统的高效性。
PAXOS容错机制
分布式容错
区块链,有一种理解为分布式统一账本,那么分布式的架构肯定会存在一个容错的问题。这里简单概述下容错相关内容。
分布式容错约定概念:
上述大致说明了一些分布式容错的约定概念。接下来简单介绍下一些协议。
分布式系统中的共识
分布式系统采用消息传递、反馈确认,那么假设一场对话(网络环境下点对点环境):
A:明天下午2点打球?收到请回复~
网络传输
B:收到,明天下午2点一块打球,确认请回复
网络传输
A:收到,确认明天下午2点一块打球,收到请回复
网络传输
B:收到,确认回复
网络传输
。。。
其实这种需要确认的协议是无法终止的,因为存在下一阶段的确认回复,最后一次不能保证没有丢失。但是理论和工程是不一样的,设计一种考虑忽略最后一次确认消息,那么一种可容忍的协议。
这种协议这里称为“共识”,结合在分布式系统中,共识假设系统中有n个节点,允许最多有f个节点崩溃,那么正常工作节点就是n-f,认为系统中至少要有n-f个节点是正常的。某一个节点发起请求x,那么在这样的环境中系统还是能达到最终一致。这个系统一致还要求三个条件:
理想化的两阶段协议
step-1
客户端发起请求至所有分布式的服务器
step-2
if
发起请求的客户端获得了所有的服务器的锁
then
客户端一次发送消息,结束后解锁
else
客户端未获得所有服务器的锁
重新进入step-1
end
这是一个理想化的模式。类似数据库系统,第一阶段就是事务的准备阶段,第二年阶段就是提交或者回滚。
问题:
那么通过两阶段,出现节点故障的状态,那么请求无法完全,理想化的两阶段协议必须要求节点都正常,如果只是一部分服务器处于锁的状态,将无法正常完成整个过程。且客户端将无法判断服务器节点锁的状态,导致系统出现故障,问题:如何有效解决这种这种模式?
PAXOS
在票上加一个序列号,服务节点在收到票的时候记录票的序号,保证票不重复和本地记录的一致。通过超过半数的票来作为容错机制。
票协议:
step-1
客户端向所有节点发送带序号的票
step-2
if
客户端收到半数服务节点收到票的回复
then
客户端再次发起票,且加上命令消息一起发送给所有服务器
服务器节点收到消息,判断票有效性后,存储命令消息
服务器返回客户端信息
else
客户端等待,返回step-1
end if
step-3
if
客户端收到半数服务器的返回客户端消息
客户端通知所有服务器执行之前的命令
else
客户端等待,返回step-1
end if
这种票协议还是会出现服务节点存储本地票号,但是客户端在发起请求的时候票号会不一致,且命令存储会出现不一致。故再对这种模式进行改进。
PAXOS大致流程:
引入本地记录票号的计数、半数确认容错。
服务端 | 客户端 |
---|---|
初始化 | 初始化 |
票号t=0、命令c | 票号Tmax=0、命令C、存储命令的票Tc |
step-1 | step-1 |
发起请求、t=t+1,请求票号为t | |
服务节点判断:t>Tmax、那么Tmax=t,回复确认(Tc、C) | |
step-2 | step-2 |
客户端如果收到半数服务节点回复确认、选择(Tc、C)验证Tc>0、那么c=C、发送消息p(t、c ) | |
服务节点收到p、判断t=Tmax、那么C=c、Tc=t、回复成功 | |
step-3 | step-3 |
接收到半数以上服务节点回复成功,向每个服务节点发送执行c操作 |
说明:
PAXOS中有三阶段,三角色(提案者、接收者、学习者)
上述流程中一个p(t、c)称为一个提案,那么提案根据算法存储在半数以上的服务器,那么后续再出现新的p(t、c)则因为t的顺序判断,故会顺序执行。可以通过反证法,同时出现两个p(t、c)出现在服务节点,且都超过半数,那么两个p提案在服务器之间肯定会有一个不为空的交集。根据两个p中t的顺序号,那么肯定有一个p提案被存储在服务器节点中,成为有效提案。在step-2中t为判断为与最高票编号比较,于是执行之前已经存储的p提案中的c命令。
场景分析:
Leslie Lamport 1989年提出了Paxos这个词汇,但是论文在1998年发表,论文太过于艰涩,很多人都无法明白。
1998年分布式系统问题已经开始受到重试,2006年谷歌大数据相关论文中,在大数据管理核心技术-容错方面采用了Paxos相关机制,故Paxos开始受到的普遍的关注和重视。
Paxos的应用:
数据库相关:Chubby、ZooKeeper、Nutanix等
域名服务器:Name Server
配置管理:config管理。
RAFT算法
RAFT算法引用原文论文翻译的第一句话:RAFT是一种为了管理复制日志的一致性算法(https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md)。
同样RAFT算法中也先引入几个角色和概念:
Leader:领导者
Follower:群众
Candidate:竞选者
Term:任期
构建一个现实的环境场景来帮助理解,在一个封闭网络中,有多个分布式节点,节点间开始权利和义务一样,互相平等,然后通过一种投票的模式:
首先所有节点都是群众,开始投票,所有群众可以参与投票也可以参与竞选,参与竞选的群众就变成了竞选者,然后选择领导者,对领导者有一个任期的概念,在选举结束后,领导者开始任期,之前候选人变成群众,直到第二期选举开始。
每个节点的角色随着投票选举过程一直在群众-竞选者-领导者-群众之间转换。
再细分下整个过程:
领导者的选举过程
所有网络中的节点,一开始都是群众,投票开始节点A、B、C等节点都转变为竞选者,这里会有一个问题,之前有个朋友也问过我,每个人都投自己那么这个领导者怎么出来,这个环节其实很有意思,每个人投票开始时间不同,那么都有一个超时时间的控制,一旦出现超时还没有选出领导者,那么超时部分节点就变成了群众,他就必须在随机休息一段时间、再次投票就只能去投其他的竞选者,这个问题也就解决了。这样的模式下来领导者很快就能出现。
领导者在整个系统中用来确保分布式集群的一致性,客户终端发送请求至领导者,领导者接受一个未确认信息、然后把未确认信息发送给群众节点,收集群众节点的返回信息,一旦超过半数节点返回,领导者再发送信息给客户端,确认信息,确认信息后,领导者再发送确认信息给群众节点,确保信息一致。
选出领导者后,那么领导者一直和网络中其他节点进行心跳通信,一旦一段时间内领导者没有发出通信,那么就认为领导者出现不确定故障(主机宕机、网络故障等),那么就再发起一轮新的选举。
再假设几个场景:
1.领导者在接收客户端消息的时候出现故障。这个时候领导者和客户端就失去联系,客户端认为超时,那么领导者上没有数据,同样群众节点也就不会有数据,这个时候确定领导者出现问题就执行再次选举操作。
2.客户端数据到达领导者,领导者发送到至群众节点,群众节点数据一致,但是这时候领导者出现故障,那么这时候即刻进行领导者选举,客户端这时候虽然不知道数据是否递交成功,但是可以尝试重新提交,这时候RAFT通过内部去重方式保证一致性。
3.数据到达领导者,领导者部分发送成功给群众节点,领导者出现故障,那么RAFT模式要求投票选举时候只能拥有最新的数据的节点才能成为竞选者,新的领导者出现数据再次同步,保证一致性。
4.数据到达领导者,发送给群众节点,领导者已提交确认,但是群众节点未全部确认,那么这时候同样2的方法处理重新选举,去重后再保证一致性。
5.数据到达领导者,发送给群众节点,所有节点提交,但是领导者未响应客户端,这个时候其实数据已经一致,故可重复操作无影响。
6.网络脑裂出现双领导者,这种方式下会出现两个领导者分区,但是多数原则保证有一个领导者会提交不成功,所有只能等待网络恢复,更新TERM后,领导者降级后在同步数据一致性。
最后对选择过程中的时间再说明:
选举过程是有一个时间限制,就像上文说到一直自己投自己情况如何控制,选择过程中有超时时间设定,然后中间会有一个分裂投票的概念(split vote),这个时候两个竞争者都要求大家投票给自己,两个竞争者在选举时间内得到相同的票,那就再发起投票,在一段时间内只对两个竞争者发起投票,首先发起的理论上得到更多的同意,那么另外一个就称为群众。
简单对RAFT算法做了一个说明,想要深入了解的可以查一下网址:https://raft.github.io/
PBFT算法
算法概要
这个算法在只读过程中只使用一次消息往返,在只写过程中只使用两次消息往返。且在正常操作中使用消息验证码(MAC),公钥加密只在发生失效的过程中使用。
参考:https://www.jianshu.com/p/fb5edf031afd
https://m.2cto.com/kf/201607/527570.html
整理说明PBFT算法概念和过程。
算法前提
- 系统是异步分布式。
- 节点失效独立。
- 系统中恶意节点不能无限期延迟正确节点,且无法破解加密算法。
- 算法提供不超过(n-1)/3的情况下保证安全性和活性。
- 系统中通过访问控制来限制失效客户端造成的破坏,审核阻止客户端的操作。
- 失效副本不超过(n-1)/3,延迟不会无限增长。这个时间是发送消息到最后接收的时间间隔。
算法中使用的相关词汇
- 公钥签名(RSA算法)
- 消息验证编码(MAC)
- hash函数生成的消息摘要(message digest)
- m表示消息
- mi表示节点i签名的消息
- D(m)表示消息摘要
- 状态(state)
- 多个操作(operations)
- 副本服务:算法实现确定性的副本复制服务,操作可读可写,基于状态和操作进行任意确定性的计算,副本的复制由n个节点组成。
- 安全性:副本复制服务满足线性一致性,理解中心化系统的原子化操作。
- 活性:依靠同步提供活性,客户端最终都会收到请求的回复。
- 副本集合R
- |R|=3f+1 |R|表示副本集合个数
- f失效的副本
- view:所有副本在一个view视图中
- primary:主节点
- backups:其他的备份副本
n>3f
f为失效节点,那么系统中必须存在3f+1个节点,原因如下:
- 系统中在n-f个节点通讯后,必须要做正确的判断。
- f个副本失效,不返回响应
- f个副本没有失效,但不返回响应
- 系统需要足够的支持响应,那么响应必须超过失效的,n-2f>f
- f个失效节点,那么在剩余的节点中必须要有一半以上的节点有正确回应,那么加起来就是3f+1个节点中,有f+1回应才能保证消息正确。
算法准备说明:
- 首先:主节点由公式p = v mod|R|计算得到,这里v是视图编号,p是副本编号,|R|是副本集合的个数。在主节点失效后启动视图更换。
- 三个阶段(预准备、准备、确认)
- 客户端client:发送请求
- 主节点primary:负责给所有客户端请求排序,然后按序发送给备份节点。
- 备份节点backups:检查序号合法性,并通过超时机制判断主节点异常。