分布式系统相关概念
一致性hash
一个设计良好的分布式系统应该具有良好的单调性,即服务器的添加与移除不会造成大量的哈希重定位,而一致性哈希恰好可以解决这个问题
一致性哈希算法是在哈希算法基础上提出的,在动态变化的分布式环境中,哈希算法应该满足的几个条件:平衡性、单调性和分散性。
1,平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题。
2,单调性是指在新增或者删减节点时,不影响系统正常运行。
3,分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据。
一致性算法Paxos
第一轮 Prepare RPCs:
请求(也叫 Prepare 阶段):
Proposer 选择一个提案编号 n,向所有的 Acceptor 广播 Prepare(n) 请求。
这里 Prepare(n)不包含提案的值。
响应(也叫 PROMISE 阶段):
Acceptor 接收到 Prepare(n) 请求,此时有两种情况:
如果 n 大于之前接受到的所有 Prepare 请求的编号,则返回 Promise() 响应,并承诺将不会接收编号小于 n 的提案。如果有提案被 Chosen 的话,Promise() 响应还应包含前一次提案编号和对应的值。
否则(即 n 小于等于 Acceptor 之前收到的最大编号)忽略,但常常会回复一个拒绝响应。
所以,Acceptor 需要持久化存储 max_n、accepted_N 和 accepted_VALUE
第二轮 Accept RPCs:
请求(也叫 PROPOSE 阶段):
当 Proposer 收到超过半数 Acceptor 的 Promise() 响应后,Proposer 向多数派的 Acceptor 发起 Accept(n, value) 请求并带上提案编号和值。(注:这里讲义的算法流程图是向所有的 Acceptor 发起 Accept() 请求,鄙人认为应该改为向多数派 Acceptor 发起。)
注意:Proposer 不一定是将 Accept() 请求发给有应答的多数派 Acceptors,可以再选另一个多数派 Acceptors 广播 Accept() 请求。
关于值 value 的选择:如果前面的 Promise 响应有返回 accepted_VALUE,那就使用这个值作为 value。如果没有返回 accepted_VALUE,那可以自由决定提案值 value。
响应(也叫 ACCEPT 阶段):
Acceptor 收到 Accept() 请求,在这期间如果 Acceptor 没有对比 n 更大的编号另行 Promise,则接受该提案。
缺陷
该算法存在活锁的缺陷,如果频繁的有Proposer 持续的发出较大的N 值,那么会导致所有的节点无法选定值。
当 Proposer 在第一轮 Prepare 发出请求,还没来得及后续的第二轮 Accept 请求,紧接着第二个 Proposer 在第一阶段也发出编号更大的请求。如果这样无穷无尽,Acceptor 始终停留在决定顺序号的过程上,那大家谁也成功不了。
解决活锁最简单的方式就是引入随机超时,这样可以让某个 Proposer 先进行提案,减少一直互相抢占的可能。
raft共识协议介绍
引入主节点,通过竞选。
节点类型:Follower、Candidate 和 Leader
Leader 会周期性的发送心跳包给 Follower。每个 Follower 都设置了一个随机的竞选超时时间,一般为 150ms~300ms,如果在这个时间内没有收到 Leader 的心跳包,就会变成 Candidate,进入竞选阶段。
流程:
1.下图表示一个分布式系统的最初阶段,此时只有 Follower,没有 Leader。Follower A 等待一个随机的竞选超时时间之后,没收到 Leader 发来的心跳包,因此进入竞选阶段。
2.此时 A 发送投票请求给其它所有节点。
3.其它节点会对请求进行回复,如果超过一半的节点回复了,那么该 Candidate 就会变成 Leader。
4.之后 Leader 会周期性地发送心跳包给 Follower,Follower 接收到心跳包,会重新开始计时。
多个 Candidate 竞选
1.如果有多个 Follower 成为 Candidate,并且所获得票数相同,那么就需要重新开始投票,例如下图中 Candidate B 和 Candidate D 都获得两票,因此需要重新开始投票。
2.当重新开始投票时,由于每个节点设置的随机竞选超时时间不同,因此能下一次再次出现多个 Candidate 并获得同样票数的概率很低。
日志复制
1.来自客户端的修改都会被传入 Leader。注意该修改还未被提交,只是写入日志中。
2.Leader 会把修改复制到所有 Follower。
3.Leader 会等待大多数的 Follower 也进行了修改,然后才将修改提交。
4.此时 Leader 会通知的所有 Follower 让它们也提交修改,此时所有节点的值达成一致。
参考:
一致性hash
https://blog.csdn.net/qq_40551994/article/details/100991581
paxos
http://tangwz.com/post/consensus/
http://tangwz.com/post/basic-paxos/