腾讯云分布式高可靠消息队列 CMQ 架构

在分布式大行其道的今天,我们在系统内部、平台之间广泛运用消息中间件进行数据交换及解耦。CMQ 是腾讯云内部自研基于的高可靠、强一致、可扩展分 布式消息队列,在腾讯内部包括微信手机 QQ 业务红包、腾讯话费充值、广告订单等都有广泛使用。目前已上线腾讯云对外开放,本文对腾讯云CMQ核心技术原理进行分享介绍。

CMQ 消息队列主要适用于金融、交易、订单等对可靠性、可用性有较高要求的业务场景。

以腾讯充值系统为例,该充值系统通过 CMQ 对交易模块、发货部分、结算系统进行异步解耦、削峰填谷,一方面大大降低了模块间耦合度,另一方面减轻了大量突发请求对后端系统的冲击。在月初充值该系统 一天经过 CMQ 转发的消息超过十亿条,每秒峰值超过 10w,最高时有数亿条消息通过 CMQ 的堆积能力缓冲了对后端消费模块的压力。

架构如图1:

图1-某充值系统结构

图中腾讯云消息队列 CMQ 整体结构如图2所示,本文重点介绍后端 broker set 实现原理。通常情况下一个 set 由 3 个节点组成,通过多副本保证消息的可靠性、多节点提高系统可用性。当然,可以根据业务的实际需求通过增加 set 内节点个数来进一步提高可靠性和可用性,

图 2-CMQ 整体架构图

CMQ set 模块内部结构如图 3 所示。

图 3-brokerset 内部结构图

下面分别中数据高可靠、强一致,系统可用性,可扩展、消息全路径追踪方面分别介绍。

在可靠性保证方面主要包括以下三方面:生产可靠、存储(堆积)可靠、消费可靠。


生产可靠

如图 3 所示,客户端生产的消息在 set 中超过半数的 broker 刷盘成功后会返回确认消息告知生产消息成功。如果在一定时间之内客户端没有收到确认信息需要重试来确保消息发送成功。

可靠生产带来的一个问题就是消息的重复,在网络异常等情况下很可能 CMQ broker 已经存储消息成功只是确认包在网络上丢失了,这样客户端重试生产后,在 broker 上存在两条重复的消息。考虑到消息去重开销较大,目前消息的幂等性需要业务逻辑来保证。


存储可靠

CMQ SET中一个节点为 leader 其他节点为 follower,leader 负责所有消息的生产消费。当生产消息到达 leader 节点后,通过 raft 一致性模块将请求顺序写 raft log 并同步刷盘,同时将构造好的 raft log 按顺序通过网络发送到其他 follower 节点,follower 节点同步刷盘并返回成功。当 leader 收到过半数的节点同步成功信息后将此条请求提交到 mq 处理状态机,由 mq 状态机将请求应用到相应 queue 。大致逻辑图 4 所示。

图4-数据存储原理示意图

由此可见,对于返回客户端成功的消息至少是分别在两个节点磁盘上存储成功的,这就将磁盘故障引起的数据丢失大大降低。另外数据在磁盘上存储时会将检验结果一同记下来,消费者在消费数据之前 CMQ broker 会进行比较,确保消息是完整有效的。


消费可靠

消费者拉取消息时会指定当前消息的隐藏时间,在隐藏时间内消费者比较显式的对消息进行确认删除,如果超过隐藏时间没有主动删除,此条消息将重新对外可见,可以继续消费。

显式确认删除消息是为了防止消息在投递、处理过程中异常而导致的消息丢失。

对于消息的确认信息 CMQ broker 的处理逻辑和生产消息过程类似,也是一个写入的过程,不同的是此时写入的数据的内容是 msgid 和消息状态。


强一致实现

假如一个 set 中有 3 个节点(A, B, C),A为 leader,B  C 是 follower 。如上图所示,对于返回客户端成功的请求数据在 CMQ 中至少在两个节点上存在,假设为 A B,此时如果 leader A 故障,B C 两个 follower 会自动选举出一个新 leader,CMQ 使用的 raft 算法可以保证这个 leader 一定是拥有最全量 log 信息中的一个,在此必定是 B。此时 B 继续对外服务,B 和 A 拥有相同的已经返回确认给用户的全量数据视图,数据是强一致的。

对于A 和 B C 所在的网络发生分区的情况(如图5),由于 leader A 得不到 set 中过半节点的回复所以不能处理请求,B C 在选举超时后会选举出一个新的 leader  ,CMQ 的接入层会自动进行切换。 Raft 算法保证新 leader 同样具有完成的数据视图。


可用性保证


如上文所述,master 负责所有消息的生产消费,当 master 故障时 SET 中其他 follower 节点会自动选举出一个新 leader,客户端请求会自动重定向到 leader 节点,RTO 和配置的选举超时时间有关,目前是在 5s 左右。大致过程如上图 6 所示。

CMQ 单个 set 在CAP理论中优先保证了CP,当SET中过半数节点都正常工作时,才能进行消息的生产消费。对于 SET 多个节点同时故障的不可用情况,CMQ 强大的监控调度能力能够快速对 queue 进行调度迁移恢复服务,将不可用时间降到最低。


横向扩展,无限堆积


上文中 SET 的概念对用户来说是透明无感知的,CMQ controller server 根据 set 的负载情况实时对 queue 进行调度搬迁。如果某个 queue 的请求量超过当前 set 的服务阈值,controller server 可以将 queue 路由分布到多个 set 上来提高并发量,对于需要海量堆积的服务来说可以通过路由调度来提升堆积上限,理论上可以达到无限堆积。

目前 CMQ 只能保证特定情况下消息的严格有序,例如需要保证单个生产进程、单个消费进程,或者 queue 的消费窗口设定为 1 等条件。


全路径消息trace

CMQ系统中,一条消息的完整路径包含生产者、broker、消费者三个角色,每个角色处理消息的过程中都会在trace 路径中增加相关的信息,将这些信息汇聚即可获取任意一条消息的状态和当前经过的完整路径,从而为生产环境中的问题排查提供强有力的数据支持。大大降低了业 务定位问题的难度。


小结

CMQ 是基于 raft 算法来保证数据高可靠、强一致的分布式消息队列,主要服务于订单、交易类业务场景。消息的幂等性需业务侧来保证,在特定情况下可以保证消息严格有序。

对于更侧重高性能、高吞吐量业务需求,腾讯云由另外一个消息引擎来提供服务,在协议上同时兼容 kafka,很好的满足了大数据场景,具体原理请留意后续文章介绍。

 

点击「阅读原文」可在腾讯云技术社区「腾云阁」阅读本文

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值