版权声明:本文由张浩原创文章,转载请注明出处:
文章原文连接:https://www.qcloud.com/community/article/126html
来源:腾云阁 https://www.qcloud.com/community算法
在分布式大行其道的今天,咱们在系统内部、平台之间普遍运用消息中间件进行数据交换及解耦。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等条件。
CMQ系统中,一条消息的完整路径包含生产者、broker、消费者三个角色,每一个角色处理消息的过程当中都会在trace 路径中增长相关的信息,将这些信息汇聚便可获取任意一条消息的状态和当前通过的完整路径,从而为生产环境中的问题排查提供强有力的数据支持。大大下降了业务定位问题的难度。
CMQ是基于raft 算法来保证数据高可靠、强一致的分布式消息队列,主要服务于订单、交易类业务场景。消息的幂等性需业务侧来保证,在特定状况下能够保证消息严格有序。 对于更侧重高性能、高吞吐量业务需求,腾讯云由另一个消息引擎来提供服务,在协议上同时兼容kafka,很好的知足了大数据场景,具体原理请留意后续文章介绍。