Raft 算法原理及其在 CMQ 中的应用(下)

《Raft 算法原理及其在 CMQ 中的应用(上)》

三 Raft在CMQ中的应用

早期我们在rabbitmq的基础上搭建了一套可扩展消息中间件CRMQ1.0,由于rabbitmq的GM同步算法在性能等方面存在瓶颈,所以自研了基于raft算法的内部版本CRMQ2.0和腾讯云CMQ,在保证强一致高可靠的前提下,性能和可用性都有显著提升。实现上采用了生产Confirm + 消费Ack机制保证消息不丢失,Confirm和Ack机制均通过raft来保证。生产的消息通过Raft转为Entry同步到大多数节点并提交,完成后各节点状态机应用该Entry,将消息内容写入磁盘,之后由Leader节点回复客户端Confirm,表示消息生产成功。消费时客户端从Leader节点拉取消息,消费完成后通过Ack命令通知服务端消息已消费可删除,Ack请求经Raft同步后,各节点应用该请求,之后消息被删除不会再投递。下面介绍详细过程:

生产流程:

1)生产者将生产消息的请求发往Leader的Raft模块。

2)Raft模块完成Entry的创建和同步。

3)大多数节点上持久化并返回成功后Entry标记为Committed。

4)所有节点的State Machine应用该日志,取出实际的生产请求,将消息内容写入磁盘,更新ApplyIndex。该步骤不需要刷盘。

5)Leader回复客户端Confirm,通知生产成功。

6)如果此后机器重启,通过raft日志恢复生产消息,保证了已Confirm的消息不丢失。

消费流程:

1)消费者从Leader节点拉取消息。

2)Leader收到后从磁盘加载未删除的消息投递给客户端。

3)客户端处理完成后Ack消息,通知服务器删除消息。

4)Ack请求经Raft同步后标记为Committed。

5)各节点状态机应用该日志,将消息对应的bit置位,将其设置为已删除并更新ApplyIndex。

6)通知客户端删除成功。

7)如果机器重启,通过Raft日志恢复Ack请求,保证了已删除的消息不会再投递。

快照管理:

快照管理与业务紧密相关,不同系统快照制作的成本差异很大,CMQ中快照的内容十分轻量,一次快照的耗时在毫秒级,平均5min创建一次,各节点独立完成。实现上内存中维护了一份动态的快照,制作快照时首先拷贝出动态快照的副本,之后处理流继续更新动态快照,用拷贝出的副本创建快照文件,不影响实际的处理流。快照具体内容包括:

1)term:快照对应Entry的term (参照算法)

2)index:快照对应Entry的 index (参照算法)

3)node_info:Entry时的集群配置信息。

4)topic info:每个队列一项。CMQ中同一队列生产的消息顺序写入,分片存储,因此只需记录最后一个分片的状态(分片文件名,文件偏移量)。

5)queue info:每个队列一项。CMQ中采用bitmap记录消息的删除情况,在内存中维护,在制作快照时dump到快照文件。

可靠性:业界统一的衡量标准为RPO(Recovery Point Objective),反映故障时数据恢复完整性的指标。由于只有提交的日志才会被应用到状态机,且raft日志在写入时会强制刷盘,所以故障重启后通过快照+raft日志即可恢复,不会丢失数据,RPO=0。不过,如2.7节所述,Leader故障时可能会产生重复数据,需要通过幂等性保证或去重机制来解决该问题。

可用性:业界统一的衡量标准为RTO(Recovery Time Objective),反映故障时业务恢复及时性的指标。follower故障对系统没有影响(RTO=0),leader故障时其他节点通过自发选出新leader,而且CMQ中前端具备自动重连功能,当连接断开后会自动寻找新leader,系统不可用时间大大降低。目前CMQ中配置的选举超时时间为2s~4s,在不考虑选举冲突的前提下,RTO上限为4s。

在CMQ中,Leader通过与Follower的心跳判断自己是否已网络分区,当检测到分区时(大多数节点上次心跳回复时间距现在超过2s),主动断开前端连接,前端发现后会自动寻找新Leader。这段时间内客户端请求会超时,在连上新Leader后,客户端重试之前超时的任务,后续请求恢复正常。

四 Raft算法性能优化

Raft算法的性能瓶颈主要有两方面:

1) 每次日志写入后都需要刷盘才能返回成功,而刷盘是一个比较耗时的操作。

2) 由于算法限制,所有的请求都由Leader处理,不能做到所有节点皆可提供服务。

针对以上两个问题,我们做了以下优化:

1)Batch Processing:在请求量较大时,并不是每一条日志写入都刷盘,还是累积一定量的日志后集中刷盘,从而减少刷盘次数。对应的,在同步到Follower时也采用批量同步的方式,Follower接收后将日志批量写盘。

2)Multi-Raft: 进程中同时运行多个raft实例,机器之间组建多raft 组,客户端请求路由到不同的group上,从而实现多主读写,提高并发性能。通过将leader分布在不同机器上,提高了系统的整体利用率。

3)Async-rpc: 在日志同步过程中采用同步rpc方式,在一端处理时另一端只能等待,性能较差。我们采用异步的方式使得leader端发送和Follower端处理并发进行。发送过程中leader端维持一个发送窗口,当待确认的rpc数达到上限停止发送,窗口值上限:

在与同属于高可靠(多副本同步刷盘)的Rabbitmq性能对比中,相同压测场景下CMQ速度可以达到RabbitMQ的四倍左右。

以下为TS60机器1KB消息大小时性能数据:

测试中CMQ采用单Raft组方式以保证测试公平性。监控显示CPU、内存和网卡均未达到瓶颈,系统瓶颈在磁盘IO,iostat显示w_await远大于svctm。主要原因在于刷盘耗时,造成写操作排队等待。

实际生产环境CMQ中我们将raft组和磁盘进行绑定,实现raft组之间磁盘的隔离,一方面保证了磁盘的顺序读写,另一方面充分利用机器的cpu 、内存、网卡等资源。

五 通用Raft库

CMQ中完整实现了Raft算法并解决了很多细节难点。考虑到分布式系统设计的复杂性,如果开发者只专注于业务相关部分,将可以显著降低开发难度,提高系统的质量,所以我们将CMQ中的raft部分以库的方式独立出来,使用者用它即可搭建一套强一致高可用分布式系统。目前该库已经完成基线版本开发并在部门落地使用,验证完成后会陆续开放给更多业务使用。

六 总结

消息中间件通常分为高可靠版本和高性能版本两种。CMQ是一款金融级的高可靠分布式消息中间件,通过raft保证了消息的可靠不丢失。同时在性能和可用性方面相比竞品都有显著提高。此外,我们自研的高性能版本的消息中间件ckafka也已在腾讯云上线,完美兼容kafka0.09~0.10版本客户端,关于CKafka的具体技术介绍请关注后续技术文章。

Raft算法强调了Leader的地位,选举和日志同步都是围绕Leader展开。由Leader负责处理所有请求保证了系统的强一致性;Leader选举和日志同步算法保证了数据的可靠不丢失;此外上述步骤只需要大多数正常互联即可,从而极大提高了系统的可用性,少量机器故障不受影响。不过,所有请求由Leader处理并没有充分利用从节点的资源,目前google的Spanner已支持从从节点读取,后续我们也会在这方面作更进一步的研究。Raft算法易于理解和工程化,相信未来会应用在越来越多的分布式系统中。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

Apache ZooKeeper vs. etcd3

在实现分布式服务协调方案时,有许多出色的系统,如 Apache ZooKeeper,etcd,consul 和 Hazelcast。如果您还没有听说过分布式协调...

3162
来自专栏知识分享

ESP8266使用详解ESP8266使用详解--基于Lua脚本语言轻松使用8266轻松使用ESP8266

Lua语言开发,感觉应该用lua http://www.cnblogs.com/yangfengwu/ 这两天测试发现一个地方写错了 发送数据的地方 最近自己做...

3087
来自专栏Jerry的SAP技术分享

微信程序开发系列教程(一)开发环境搭建

2. 这个教程使用nodejs开发微信订阅号对应的消息服务器,因此需要具备基本的nodejs开发技能。

1054
来自专栏友弟技术工作室

docker拾遗-之再入坑

1536
来自专栏架构师之路

这才是真正的分布式锁

昨晚十点下班,回家花了1个小时写了一篇《一分钟实现分布式锁》,引起读者一些反响,有些朋友反馈“setnx算什么方案”,“没有考虑超时”,“为啥不用zookeep...

3707
来自专栏散尽浮华

Heartbeat使用梳理

在日常的集群系统架构中,一般用到Heartbeat的主要就2种: 1)高可用(High Availability)HA集群, 使用Heartbeat实现,也称为...

2287
来自专栏互联网杂技

HTTP,HTTP2.0,SPDY,HTTPS你应该知道的一些事

作为一个经常和web打交道的程序员,了解这些协议是必须的,本文就向大家介绍一下这些协议的区别和基本概念,文中可能不局限于前端知识,还包括一些运维,协议方面的知识...

38711
来自专栏blackheart的专栏

[信息安全] 3.HTTPS工作流程

0. 简单回顾 在前面两篇博客中介绍了密码相关的一些基本工具,包括(对称密码,公钥密码,密码散列函数,混合密码系统,消息认证码码,数字签名,伪随机数,数字证书)...

2095
来自专栏ImportSource

扒扒HTTP缓存

摘要: 本文会从理论和实战两方面描述http缓存。理论层面会介绍:缓存命中、缓存丢失、Revalidations(重新验证)、命中率(Hit Rate)、字节...

3286
来自专栏Java技术分享

Dubbo详细介绍与安装使用过程

1 Dubbo介绍 1.1 dubbox简介 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟...

3678

扫码关注云+社区