深入浅出 Raft - Optimization

百家 作者:PingCAP 2017-11-06 12:16:18

本文为我司首架唐刘老师的小猪佩奇版“深入浅出 Raft”第三弹。前两篇内容戳这里 → 深入浅出 Raft - 基本概念深入浅出 Raft  - Leader 选举

在猪爸爸的努力下,三个银行网点能正确的选出一个主网点对外提供服务了。一切工作的良好,但随着客户的增多,一些问题渐渐暴露出来。

这天,兔小姐又叫来了猪爸爸,说到:『猪爸爸,现在我们碰到了一个问题。每次客户在 Leader 网点进行一笔交易,我们都需要告诉其他两个地方,只有我们确定了交易记录被大多数网点保存了,这笔交易才会真正开始执行,处理完了,我们才能继续服务下一个客户。已经有很多客户投诉我们效率慢了。』

『是的,兔小姐,之前我们设计的机制只能保证整个系统在出现了异常的时候,能够安全的运行,不会出现金钱不一致的情况。现在,是时候考虑对整个系统进行优化了,而且我已经想到了很多优化的手段。』猪爸爸信心满满的说到。

『那真的是太好了』兔小姐高兴的说到,『你能跟我好好的说一下嘛?』
『当然可以!』

Pipeline 和 Batch

『首先,我们来整理下现在的流程,假设客户来存钱,我们会先记录交易,然后给其他几个网点发送消息,等我们确定大部分网点都确认了这笔交易记录,就可以开始执行这笔交易,将用户的钱存到金库里面了。』
『是的,猪爸爸』
『现在,为了后面简单说明,我将整个流程简化说明一下,其实就是几个步骤,也就是 Propose,Append,Broadcast 和 Apply。客户发起交易,我们叫做 Propose,然后我们记录交易,这个叫做 Append,再就是通知其他网点,这个叫做 Broadcast,等我们最后知道大部分网点都确认了这笔交易记录,我们就执行交易,也就是 Apply。希望我这么简化不会让你困惑,兔小姐。』猪爸爸有点担忧的询问到。
『虽然有点抽象了,但我想我还是能理解的,猪爸爸。麻烦你继续。』
『好的,兔小姐,既然你理解了简化流程,那么我下面开始说第一个优化,就是 Pipeline。』
『Pipeline?这是什么,你完全把我搞糊涂了,猪爸爸』兔小姐吃惊的说到。
『不要紧张,兔小姐。Pipeline 就是管道,你可以把我们的整个流程想成一个 Pipeline。对于客户 A,操作是 Propose,Append,Broadcast, Apply,对于客户 B 也是一样的流程,之前我们必须等 A 完成了,才能处理 B。但不知道你发现了没有,兔小姐,当 A 在 Append 之后,我们就可以开始处理 B 的 Propose 了。』
『为什么呢?猪爸爸,我有点不明白了』
『我们只要保证的是所有银行网点的交易记录是一致有序的,那么我们就一定能保证最终所有银行的数据是一致的,所以只要 A Append 了,B 开始 Propose,B Append 的时候交易记录一定在 A 的后面,这样记录就一定是有序的了。』
『我大概有点理解了。』兔小姐说到。
『所以,兔小姐,当 A 执行完 Append 之后,我们就能立刻开始处理 B,而当 B Append 之后,我们也可以立刻处理下一个用户 C,这样整个流程就是一个像水流那样源源不断流动的了,这不就是一个 Pipeline 了。』
『嗯,真的是很形象,猪爸爸。』兔小姐由衷的赞叹道。

Batch

『我们还可以继续优化了,兔小姐。上面我们说到了 Pipeline,我们还可以做 Batch。』猪爸爸继续说道。
『Batch?』兔小姐疑惑的说道。
『是的,Batch。也就是我们可以将很多单独的操作合并到一块处理。』
『哦,这个我明白。』兔小姐说道,『可哪里做 Batch 呢?』
『如果很多客户同时要发起交易,那么我们可以将这些交易记录,用一个消息发送过去到其他网点,这样我们就不需要一个一个的发送消息了,这就是 Batch。』
『哦,我明白了。因为我们各个网点之间距离还是有点远的,消息传递的时间开销还是有点大的。所以使用 Batch 可以减少消息的发送次数,自然就能提高效率了,是吧,猪爸爸。』
『非常正确,兔小姐。』

Leader 并发写盘

上面说到了 Pipeline 和 Batch,这里我们再次说明一下整个 Raft 的流程。Leader 收到 Propose,Append Log,然后 Broadcast Log,等收到 Follower 的回复确定 Log 被 Committed 之后,开始 Apply。而对应的 Follower,在收到 Log 之后,先 Append Log,然后给 Leader reply 消息,等下次 Leader 发过来的消息知道 Log 被 Committed 了,就可以 Apply 了,好了,我们继续说故事吧。

『猪爸爸,有了 Pipeline 和 Batch,我们银行的服务速度应该会很快了。』
『是的,兔小姐,不过我们还可以继续优化了。』
『真的?』兔小姐有点不可思议。
『是的,你还记得我之前提到过的 quorum 吧。对于一笔交易记录,如果我们知道大部分银行网点都确认了这笔记录,我们就可以继续处理交易了。』
『当然记得,猪爸爸。』
『当用户在 Leader 网点进行交易的时候,原来我们的流程是 Propose,Append,然后在 Broadcast,但现在,我们在 Propose 之后,就可以直接 Broadcast,同时 Append,这两个步骤在 Leader 网点是可以同时处理的。』
『同时处理?猪爸爸,这没什么风险吧?』
『不会有任何风险,即使 Broadcast 先进行,Leader 网点这边仍然需要在 Append 之后确保这笔记录被大多数网点确认了。』
『我想我有点明白了。也就是这两个流程其实不相关,反正无论怎样,后面 Leader 都必须等待 Follower 回复的确认消息,才能最终确定这笔交易是否已经被大多数网点接受了。』
『对的,兔小姐。但这里我们需要注意,这个优化只能在 Leader 网点进行,在 Follower 网点这边,我们仍然需要保证先 Append,再回复。』
『哦,这又是怎么回事,猪爸爸?』
『我们上面说了,Leader 网点必须知道大部分网点都收到了交易记录,才能认为是 Committed,然后继续处理。如果 Follower 网点这边也直接先回复消息,在 Append,就可能出现一种情况,在 Append 之前,Follower 网点出现了问题,导致 Append 不成功。那么极端情况下面就会出现,Leader 认为记录都已经被大部分节点接受了,但实际并没有,我们就很可能面临数据丢失的问题了。』
『好复杂,但我貌似懂了。』兔小姐思索了一会说到。

小结

Raft 的 Paper 其实比较简单,但如果实际按照 Paper 实现,会发现性能并不好,所以在实践中,我们会做很多优化,上面提到的只是一些优化手段,还有一些,譬如 Leader 在发送一次 Log 之后不需要等 Follower 的回复,继续发送后面的 Log,Follower 只需要回复最近的一次 Log Index 或者 reject 就可以。

这些优化方式在 etcd 和 TiKV 里面都有,大家可以自己去浏览代码。


- 未完待续 -

延展阅读

深入浅出 Raft - 基本概念

深入浅出 Raft  - Leader 选举



长按关注

新型分布式 NewSQL 数据库

微信号:pingcap2015



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接
百度热搜榜
排名 热点 搜索指数