重学分布式系统(三) CAP理论与Raft算法

2,035 阅读6分钟

关于分布式相关理论与算法的介绍

1. CAP定理

分布式系统的三个指标:

  • Consistency(一致性)

在分布式系统中的所有数据备份, 在同一时刻是否还是同样的值. (写操作之后的读操作, 必须返回这个值. 更新操作执行成功之后所有的用户都应该读到最新的值, 要求所有的备份数据保持一致)

  • Availablity(可用性)

描述的是当集群中的一部分节点出现故障之后, 集群整体是否还能响应客户端的读写请求(这就要求数据冗余)

  • Partition tolerance (分区容错性)

大多数分布式系统都分布在多个子网络, 每个子网络就叫做一个区(Partition). 分区容错指的就是, 区间通信可能会失败.

CAP理论说的就是, 在分布式存储系统中, 最多只能实现上面的两点. 热由于当前的网络硬件一定会出现丢包的问题, 所以分区容错是必须实现的. 所以我们只能在一致性和可用性之间进行权衡, 没有NoSQL系统能够同时保证这三点. 所以分布式系统中, CP, AP二选一.

2. 分布式系统中实现一致性的raft算法

简介: 如果一个节点的值更新, 那么该协议会保证其他节点的值也更新为该值

每个节点有三种状态: Follower Candidate Leader.

首先所有的节点都是Follower状态, 如果有一个节点没有收到来自其他节点的信息, 那么该节点就变成Candidate状态, 并向其他节点发送投票请求, 接下来其他的节点开始投票, 如果Candidate收到大多数节点的投票, 那么该节点成为Leader. 这个系统中的所有变化都得由Leader来决定.

比如一个节点向Leader发送了一个 set 5的请求, 那么Leader节点收到之后就行Follower节点发送一条set 5的命令, Follower节点收到并执行后, 会向Leader节点回复一条信息, Leader节点收到所有的回复之后, 就会将set 5这条请求提交. 如果你在访问节点的时候, set 5这个状态并没有提交, 那么你读到的是原来的值(当然, 如果你设置的是快读的话, 读到的就是5, 主要看你对一致性的要求)

Leader提交之后, 会向Follower节点发送一条提交命令, 告诉它们我已经提价了, 你们也给我提交. 至此整个同步过程就完成了.

领导选举的过程:

有两种超时时间用来控制选举的过程

选举超时时间

每一个节点都会有一个自旋时间, 这个时间是随机的, 在150ms-300ms之间, 所以会有的节点转的块, 有的节点转的慢一点, 如果有一个节点的自旋时间转完了, 还没有收到Leader的心跳包, 那个这个节点就会成为一个Candidate, 并向其他的节点发送投票请求, 其他节点收到请求后会向该节点投票, 该Candidate便成为了Leader, 然后开始向其他节点发送心跳包, 注意, 其他的节点一旦收到了心跳包, 那么它的自旋时间将会重置

​ 您可能会疑惑, 如果有两个节点(或者更多)恰巧自旋时间差不多, 然后几乎同时发送投票请求怎么办? 这个情况下, 谁获得了大部分节点的投票, 谁就是Leader, 如果恰巧一样多, 那么又会进入自旋, 注意自旋时间随机, 所以其实自旋时间一样的概率会很小

心跳超时时间

心跳超时后, Follower没有收到心跳包, 于是自旋时间转到了之后就会成为Candidate, 然后发送投票请求啦, 成为新的Leader...

日志复制

现在我们可以更详细的谈一谈这个了, 当客户向Leader发送了一个 Set 5的请求时, Leader也需要向Follower发送这个请求来保证一致性, 那么在什么时候发送这个请求呢? 其实是在下一次发送心跳包的时候报这个命令给带过去, 然后Follower回复, Leader收到所有Follower的回复之后向客户回复提交成功的信息, 然后再下一次心跳包的时候告诉Follower: 已经提交成功了, 然后Follower提交这个请求, 即更新数据.

分区容错

如果出现了网络问题怎么办呢?

比如说有5个节点, 这个时候网线断了, Leader和只能和一个节点通信, 其他三个节点相互通信, 这个时候客户端给Leader下达的命令就无法提交了, 因为Leader知道这个分布式系统里面一共有5个节点, 但是现在只有一个节点回复了, 所以这个请求一直无法提交, 反映到客户端就是你的请求一直无法响应,.

而在另一个分区, 由于没有收到心跳包, 所以心跳超时了, 节点自旋结束后就开始选举了, 这时选举出来了一个新的节点, 另一个客户端请求这个新的Leader, Leader接受了这个响应之后向Follower发送心跳包并附带上这个请求, 由于这个分区有3个节点, 占了一大半, 所以这个请求可以提交, 于是客户端的请求执行成功.

如果这个时候网络通信恢复了会怎么样呢? 这时只有两个节点的分区中的Leader发送给其他节点的心跳包可以发过去了, 但它发现已经有新Leader了, 而且选举的轮次比它高, 也就是说是更新选出来的, 于是这个Leader就变成了新Leader的Follower, 并且将之前接受的没有提交的请求回滚.

所以现在你理解了raft算法了吧, 我再划一下重点:

  • 任何时候raft系统中只能有一个Leader(网断了除外, 因为它不知道有了新的Leader了),
  • Follower不会发送任何请求, 只会响应来自Leader或者Candidate的请求, 如果接受到客户请求, 会转发给Leader
  • Candidate状态是在没有收到心跳包的情况之下才会产生
  • 选举轮数, 类似于第几届总统一样, 每一届只能有一个总统, 而且只认最新届的总统, 如果之前一届的总统断网了, 等它通网后, 也只能乖乖当Follower
  • 附加日志, Leader在发送日志与心跳的机制

3. BASE理论

Basically Available(基本可用)

Soft state(软状态): 就是一个中间状态, 你想读的话也可以把数据给你, 要是不想读的话, 等一等, 就可以给你一个最终一致的数据

Eventually consistant(最终一致性)

三个短语的简写, BASE是对CAP中一致性和可用性权衡的结果, 其来源是对于大规模互联网系统分布式时间的结论, 是基于CAP定理逐步演化而来的, 其核心思想是即使无法做到强一致性, 但每个应用可以根据自身业务的特点, 采用适当的方式来使系统达到最终一致性