一致性协议raft详解(四):raft在工程实践中的优化

一致性协议raft详解(四):raft在工程实践中的优化

前言

有关一致性协议的资料网上有很多,当然错误也有很多。笔者在学习的过程中走了不少弯路。现在回过头来看,最好的学习资料就是Leslie LamportDiego Ongaro的数篇论文、Ongaro在youtube上发的三个视频讲解,以及何登成的ppt。

本系列文章是只是笔者在学习一致性协议过程中的摘抄和总结,有疏漏之处敬请谅解,欢迎讨论。

性能优化

性能优化主要有以下几点:

  1. Writing to the leader’s disk in parallel Leader 可以在向 Follower 并行复制日志的同时写入自己的磁盘,如果多数派 Follower 已经写入磁盘,Leader 甚至可以在该记录写入自己的磁盘之前就提交,这仍然是安全的。
  2. Batch 和 Pipeline
    • Batch:Leader 可以一次收集多个客户端 requests,然后一批发送给 Follower。当然,我们也需要有一个最大发送 size 来限制每次最多可以发送多少数据,LogCabin 使用 1M 大小。
    • Pipeline:如果只是用 batch,Leader 还是需要等待 Follower 返回才能继续后面的流程,我们这里还可以使用 Pipeline 来进行加速。Leader 会维护一个 nextIndex 的变量来表示下一个给 Follower 发送的 log 位置,通常情况下,只要 Leader 跟 Follower 建立起了连接,我们都会认为网络是稳定互通的。所以当 Leader 给 Follower 发送了一批 log 之后,它可以直接更新 nextIndex,并且立刻发送后面的 log,不需要等待 Follower 的返回。如果网络出现了错误,或者 Follower 返回一些错误,Leader 就重新调整 nextIndex,然后重新发送 log。
      • 最初的线程架构阻碍了 pipeline,因为它只能支持每个 Follower 一个 RPC。这里 Leader 必须多线程地与一个 Follower 建立多个连接。
      • 如果 Leader 与一个 Follower 共用一个连接使用 pipeline 的话, 那么效果会是怎样的呢?其实这样和 Batch 没有多大区别,tcp 层面已经是串行的了,tcp 有滑动窗口来做 batch,同时单条连接保证了消息很少会乱序。
      • 那么,如果使用多线程连接的话可能存在什么问题?即使因为在多个连接中不能保证有序,但是大部分情况还是先发送的先到达;即使后发送的先到达了,由于有 AppendEntries RPC 一致性检查的存在,后发送的自然会失败,失败后重试即可。
  3. pre-vote:**网络分区会导致某个节点的数据与集群最新数据差距拉大,但是 term 因为不断尝试选主而变得很大。网络恢复之后,Leader 向其进行日志复制时,就会导致 Leader 因为 term 较小而下台。**这种情况可以引入 pre-vote rpc 来避免。Follower 在转变为 Candidate 之前,先与集群节点通信,获得集群 Leader 是否存活的信息,如果当前集群有 Leader 存活,Follower 就不会转变为 Candidate,也不会增加term。参考上面的段落。并且只有在获得半数以上投票之后,才会增加自己的term,然后发request vote rpc
  4. MultiRaft:raft节点过多之后,各节点间心跳开销很大。CockroachDB将raft分为raft组,心跳也分为了组间心跳和组内心跳。各个组之间每次只交换一个心跳,而不像之前那样所有的节点都会提供心跳。
  5. 在上一任leader还存在的时候,不会进行选主
    1. Leader Lease:上一任Leader的Lease过期后,随机等待一段时间再发起Leader选举,保证新旧Leader的Lease不重叠。
    2. Leader Stickiness:Leader Lease未过期的Follower拒绝新的Leader选pm举请求。
  6. 百度在上面leader stickiness的基础上,实现了静默模式:braft 提供了静默模式:通常复制组不需要频繁的切换 Leader,我们可以将主动 Leader Election 的功能关闭,这样就不需要维护 Leader Lease 的心跳了。复制组依靠业务 Master 进行被动触发 Leader Election,这个可以只在 Leader 节点宕机时触发,整体的心跳数就从复制实例数降为节点数。
  7. 针对慢节点做优化(GFS、mapreduce等存储系统中也有类似优化,不做详述了)
  8. raft功能完善

Raft 系统的整体性能在很大程度上取决于如何安排 batch 和 pipeline。如果在高负载的情况下,一个 batch 中积累的请求数量不够,整体处理效率就会很低,导致低吞吐量和高延迟。另一方面,如果在一个 batch 中积累了太多的请求,延迟将不必要地变高,因为早期的请求要等待后来的请求到达。

client对raft集群的读写

经过之前内容的阐述,我们已经明白了why what how raft,以及各种优化。现在让我们再回到一个最基本的问题上:一个客户端如何对raft集群进行读取写?

    • 由于raft协议的特性,写请求必须由leader发起,由leader负责向整个raft集群写入,写成功后返回,
    • 只要对该请求执行raft协议成功,那么必然能提供各种保证
    • 最简单可以通过Quorum方式读
    • raft因为有leader,可以从leader上去读,但是为了防止网络分区导致的假leader对raft一致性的破坏,可以用以下方式优化:
      • 对读请求也执行raft协议,会有额外的overhead
      • leader通过之前讲到的某种优化方法,确认自己是真正的leader之后,才提供读写请求服务。
  1. 客户端要有幂等性保证

参考链接

  1. The Raft Consensus Algorithm raft 官方网站
  2. RAFT介绍 百度braft写的raft介绍
  3. 理论基础 · Raft phd 论文中的pipeline 优化那么使用多条连接的话可能存在什么问题?
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值