顺序投票对复制性能的影响

顺序投票对复制性能的影响

Content #

Paxos 和 Raft 在复制效率上 Raft 会差一些,主要原因就是 Raft 必须“顺序投票”,不允许日志中出现空洞。

我们先看一个完整的 Raft 日志复制过程:

  1. Leader 收到客户端的请求。
  2. Leader 将请求内容(即 Log Entry)追加(Append)到本地的 Log。
  3. Leader 将 Log Entry 发送给其他的 Follower。
  4. Leader 等待 Follower 的结果,如果大多数节点提交了这个 Log,那么这个 Log Entry 就是 Committed Entry,Leader 就可以将它应用(Apply)到本地的状态机。
  5. Leader 返回客户端提交成功。
  6. Leader 继续处理下一次请求。

以上是单个事务的运行情况。那么,当多事务并行操作时,又是什么样子的呢?

我们设定这个 Raft 组由 5 个节点组成,T1 到 T5 是先后发生的 5 个事务操作,被发送到这个 Raft 组。

事务 T1 的操作是将 X 置为 1,5 个节点都 Append 成功,Leader 节点 Apply 到本地状态机,并返回客户端提交成功。事务 T2 执行时,虽然有一个 Follower 没有响应,但仍然得到了大多数节点的成功响应,所以也返回客户端提交成功。

现在,轮到 T3 事务执行,没有得到超过半数的响应,这时 Leader 必须等待一个明确的失败信号,比如通讯超时,才能结束这次操作。因为有顺序投票的规则, T3 会阻塞后续事务的进行。T4 事务被阻塞是合理的,因为它和 T3 操作的是同一个数据项,但是 T5 要操作的数据项与 T3 无关,也被阻塞,显然这不是最优的并发控制策略。

同样的情况也会发生在 Follower 节点上,第一个 Follower 节点可能由于网络原因没有收到 T2 事务的日志,即使它先收到 T3 的日志,也不会执行 Append 操作,因为这样会使日志出现空洞。

Raft 的顺序投票是一种设计上的权衡,虽然性能有些影响,但是节点间日志比对会非常简单。在两个节点上,只要找到一条日志是一致的,那么在这条日志之前的所有日志就都是一致的。这使得选举出的 Leader 与 Follower 同步数据非常便捷,开放 Follower 读操作也更加容易。要知道,我说的可是保证一致性的 Follower 读操作,它可以有效分流读操作的访问压力。

Viewpoints #

From #

07 | 数据复制:为什么有时候Paxos不是最佳选择?