加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

蚂蚁金服开源 SOFAJRaft:生产级 Java Raft 算法库

发布时间:2019-03-24 15:13:40 所属栏目:优化 来源:佚名
导读:副标题#e# 什么是 SOFAJRaft? SOFAJRaft 是一个基于Raft一致性算法的生产级高性能 Java 实现,支持 MULTI-RAFT-GROUP,适用于高负载低延迟的场景。 使用 SOFAJRaft 你可以专注于自己的业务领域,由 SOFAJRaft 负责处理所有与 Raft 相关的技术难题,并且 SO

3.Snapshot and log compaction:定时生成 snapshot,实现 log compaction 加速启动和恢复,以及 InstallSnapshot 给 Followers 拷贝数据,如下图:

蚂蚁金服开源 SOFAJRaft:生产级 Java Raft 算法库

本图出自《In Search of an Understandable Consensus Algorithm》

4.Membership change:用于集群线上配置变更,比如增加节点、删除节点、替换节点等。

5.Transfer leader:主动变更 leader,用于重启维护,leader 负载平衡等。

6.Symmetric network partition tolerance:对称网络分区容忍性。

蚂蚁金服开源 SOFAJRaft:生产级 Java Raft 算法库

如上图 S1 为当前 leader,网络分区造成 S2 不断增加本地 term,为了避免网络恢复后 S2 发起选举导致正在良心 工作的 leader step-down,从而导致整个集群重新发起选举,SOFAJRaft 中增加了 pre-vote 来避免这个问题的发生。

SOFAJRaft 中在 request-vote 之前会先进行 pre-vote(currentTerm + 1, lastLogIndex, lastLogTerm),多数派成功后才会转换状态为 candidate 发起真正的 request-vote,所以分区后的节点,pre-vote 不会成功,也就不会导致集群一段时间内无法正常提供服务。

7.Asymmetric network partition tolerance:非对称网络分区容忍性。

蚂蚁金服开源 SOFAJRaft:生产级 Java Raft 算法库

如上图 S1 为当前 leader,S2 不断超时触发选主,S3 提升 term 打断当前 lease,从而拒绝 leader 的更新。

  1. 在 SOFAJRaft 中增加了一个 tick 的检查,每个 follower 维护一个时间戳记录下收到 leader 上数据更新的时间(也包括心跳),只有超过 election timeout 之后才允许接受 request-vote 请求。

8.Fault tolerance:容错性,少数派故障不影响系统整体可用性,包括但不限于:

1)机器掉电

2)强杀应用

3)慢节点(GC, OOM 等)

4)网络故障

5)其他各种奇葩原因导致 raft 节点无法正常工作

9.Workaround when quorate peers are dead:多数派故障时,整个 grop 已不具备可用性,安全的做法是等待多数节点恢复,只有这样才能保证数据安全;但是如果业务更加追求系统可用性,可以放弃数据一致性的话,SOFAJRaft 提供了手动触发 reset_peers 的指令以迅速重建整个集群,恢复集群可用。

10.Metrics:SOFAJRaft 内置了基于 Metrics 类库的性能指标统计,具有丰富的性能统计指标,利用这些指标数据可以帮助用户更容易找出系统性能瓶颈。

11.Jepsen:除了几百个单元测试以及部分 chaos 测试之外, SOFAJRaft 还使用 jepsen 这个分布式验证和故障注入测试框架模拟了很多种情况,都已验证通过:

1)随机分区,一大一小两个网络分区

2)随机增加和移除节点

3)随机停止和启动节点

4)随机 kill -9 和启动节点

5)随机划分为两组,互通一个中间节点,模拟分区情况

6)随机划分为不同的 majority 分组

性能优化

除了功能上的完整性,SOFAJRaft 还做了很多性能方面的优化,这里有一份 KV 场景(get/put)的 Benchmark 数据, 在小数据包,读写比例为 9:1,保证线性一致读的场景下,三副本最高可以达到 40w+ 的 ops。

这里挑重点介绍几个优化点:

  1. Batch: 我们知道互联网两大优化法宝便是 Cache 和 Batch,SOFAJRaft 在 Batch 上花了较大心思,整个链路几乎都是 Batch 的,依靠 disruptor 的 MPSC 模型批量消费,对整体性能有着极大的提升,包括但不限于:
  2. 批量提交 task
  3. 批量网络发送
  4. 本地 IO batch 写入
  5. 要保证日志不丢,一般每条 log entry 都要进行 fsync 同步刷盘,比较耗时,SOFAJRaft 中做了合并写入的优化。
  6. 批量应用到状态机
  7. 需要说明的是,虽然 SOFAJRaft 中大量使用了 Batch 技巧,但对单个请求的延时并无任何影响,SOFAJRaft 中不会对请求做延时的攒批处理。
  8. Replication pipeline:流水线复制,通常 Leader 跟 Followers 节点的 Log 同步是串行 Batch 的方式,每个 Batch 发送之后需要等待 Batch 同步完成之后才能继续发送下一批(ping-pong),这样会导致较长的延迟。SOFAJRaft 中通过 Leader 跟 Followers 节点之间的 pipeline 复制来改进,非常有效降低了数据同步的延迟, 提高吞吐。经我们测试,开启 pipeline 可以将吞吐提升 30% 以上,详细数据请参照 Benchmark。
  9. Append log in parallel:在 SOFAJRaft 中 Leader 持久化 log entries 和向 Followers 发送 log entries 是并行的。
  10. Fully concurrent replication:Leader 向所有 Follwers 发送 Log 也是完全相互独立和并发的。
  11. Asynchronous:SOFAJRaft 中整个链路几乎没有任何阻塞,完全异步的,是一个完全的 callback 编程模型。
  12. ReadIndex:优化 Raft read 走 Raft log 的性能问题,每次 read,仅记录 commitIndex,然后发送所有 peers heartbeat 来确认 Leader 身份,如果 Leader 身份确认成功,等到 appliedIndex >= commitIndex,就可以返回 Client read 了,基于 ReadIndex Follower 也可以很方便的提供线性一致读,不过 commitIndex 是需要从 Leader 那里获取,多了一轮 RPC;关于线性一致读文章后面会详细分析。
  13. Lease Read:SOFAJRaft 还支持通过租约 (lease) 保证 Leader 的身份,从而省去了 ReadIndex 每次 heartbeat 确认 Leader 身份,性能更好,但是通过时钟维护 lease 本身并不是绝对的安全(时钟漂移问题,所以 SOFAJRaft 中默认配置是 ReadIndex,因为通常情况下 ReadIndex 性能已足够好。

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读