张   浩    腾讯云产品经理

负责腾讯云消息队列、弹性块存储、负载均衡器等多款iaas层产品的产品规划、迭代,性能体验优化等 。

闫二辉   腾讯云资深存储架构师

在大规模存储、PaaS、虚拟化领域有长期深厚积累。目前主要从事互联网中间件的设计研发相关工作。

周维跃   腾讯云资深研发工程师

负责腾讯云IaaS层虚拟化资源调度运营系统的设计研发。

目录

  1. 消息队列的使用场景、价值

  2. CMQ底层架构剖析

  3. CMQ对比开源rabbitMQ压测

  4. CMQ案例最佳实践

01|消息队列的使用场景

  • 消息的收发解耦:发送方和接收方不需要了解彼此,甚至不需要知道对方的存在;

  • 屏蔽不同平台之间的差异:不同平台之间通过消息来实现交互,仅仅关心消息的发送和读取;

  • 削峰填谷,提高系统应对突发能力:发送消息端永远不会堵塞,突发消息缓存在CMQ SERVER 端,消费者按照实际能力读取消息;

  • 一次生产多次消费:一条消息可以被多钟类型消费者订阅,生产着仅需生产一次即可;

  • 跨IDC/WAN传输:CMQ支持消息在不同IDC、城市进行生产、消费,自动就近接入,对业务透明;

02|CMQ底层架构剖析

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

按照使用场景可以将消息中间件粗略分为:高可靠和高性能两大类。CMQ主要适用于金融、交易、订单等对可靠性、可用性有较高要求的业务场景。

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


图1-某充值系统结构

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

图2-CMQ整体架构图


图3-brokerset 内部结构图

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

高可靠保证


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

  • 生产可靠

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

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

  • 存储可靠

CMQSET中一个节点为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所示,具体选举算法请参考raft 论文。

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

横向扩展,无限堆积

图7横向扩展

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

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

全路径消息trace

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

小结

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

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

03|CMQ对比开源rabbitMQ压测


RabbitMQ 是具有代表性的开源消息中间件,当前较多地应用于企业系统内,用于对数据一致性、稳定性和可靠性要求较高的场景中。
 

CMQ也是强调高可靠的消息传递,那腾讯云的CMQ,对比rabbitMQ有哪些优势?

  • 功能升级

除了生产、消费确认机制,CMQ还提供了消费回溯功能。

用户指定CMQ保存生产消息一定天数,随后将消费回溯到该时间段内某一时间点,从该点开始重新消费。在用户业务逻辑异常时,以时间为起点的消息重放功能对业务恢复非常有帮助。

  • 性能优化

网络IO:CMQ能够批量生产/消费消息,RabbitMQ则不支持批量生产。在大量小消息场景中,CMQ具有更少的请求数和更低的平均延迟。

文件IO:CMQ生产/消费消息是顺序写单个文件,并周期落盘存储,充分利用文件系统缓存。RabbitMQ持久化消息先入内存队列进行状态转换,然后写日志缓存,最后写消息文件和索引文件(索引文件为顺序写、消息文件为随机写),涉及三次IO操作,性能较差。

CPU:RabbitMQ的日志缓存和状态转换运算较复杂,大量耗用CPU。

  • 可用性提升

CMQ和RabbitMQ都能够使用多台机器进行热备,提高可用性。CMQ基于Raft算法实现,简单易维护。RabbitMQ使用自创的GM算法(Guaranteed Multicast),学习难度高。

Raft协议中,Log复制只要大多数节点向Leader返回成功,Leader就可以应用该请求,向客户端返回成功。

GM可靠多播将集群中所有节点组成一个环。Log复制依次从Leader向后继节点传播,当Leader再次收到该请求时,发出确认消息在环中传播,直至Leader再次收到该确认消息,表明Log在环中所有节点同步完成。

GM算法要求Log在集群所有节点同步之后才能向客户端返回成功;Raft算法则只要求大多数节点同步完成。Raft算法在同步路径上比GM算法减少了一半的等待时间。

  • 压测结果

经内部严格压测,在同等网络、CPU内存环境下,CMQ在保证可靠传递的前提下,QPS表现是rabbitMQ的4倍以上。

04|CMQ15年微信春晚红包案例

春晚红包活动涉及四个大型系统的联动,包括微信、微信支付、红包系统和财付通系统。以下简单介绍各个系统:

红包系统:个人红包的发、抢、拆和列表查看;

财付通系统:包括支付订单、异步入账流水的高性能存储,用户余额和账单的实时展示;

微信接入:确保微信用户公网接入的质量;

微信支付:在线交易的入口。

类似红包系统的分布式事务是关注的热点。举一个典型的例子,“用户A给用户B发了10元的红包”,有以下步骤:

  1. 从A帐号中把余额读出来

  2. 对A帐号做减法操作(减10元)

  3. 把结果写回A帐号中(一次确认)

  4. 从B帐号中把余额读出来

  5. 拆开A发送给B的红包,读出数值

  6. 对B帐号做加法操作(加10元)

  7. 把结果写到B帐号中

为了保证数据的一致性,上述步骤只有两种结果:都成功完成或者都不成功执行回滚。而且这个操作的过程中,对A、B帐号还需引入分布式锁机制来避免脏数据的问题。在微信红包这个庞大的分布式集群内,事情将变的异常复杂。

微信红包系统引入了腾讯云 CMQ 以避免分布式事务增加对系统的开销。同样A用户给B用户发10元红包的场景,下面介绍引入CMQ 后的新策略。

在上述案例中的第七步,B 用户拆开了红包,红包里有 10 块钱。在做最后的入账操作时由于当天并发压力大,常出现入账失败的情况。

红包团队把入帐失败的请求,全部转入CMQ。当B用户更新账户余额失败时,手机客户端显示等待状态。随后入账系统将不断从 CMQ 重新拉取重试此更新操作。CMQ 保证了这 10 元的入账消息永远不丢,直至它被取出。

在除夕当天,用户红包的发、拆、入账等动作,转化为了十亿级别的海量请求。若使用传统的事务方式,会放大并发压力使系统崩溃。

CMQ消息队列保证了红包消息的可靠存储、传递,实时写三份保证数据不丢。资金入账失败时,入账系统可异步的多次重试,从CMQ拉数据,直到成功,起削峰填谷的作用。避免失败回滚和频繁轮询数据库等传统方式的弊端。

Q&A

Q1:创业公司怎么选择消息队列?

A1:开源的消息队列有很多,实现机制复杂,运维成本也很高,对于创业企业来说,选择云服务商提供的消息队列无疑是最省事的,按需使用,成本非常低。

Q2:CMQ生产的消息,如果未被消费保存多久?

A2:消息在队列中最长的存活时间,从发送到该队列开始经过此参数指定的时间后,不论消息是否被取出过都将被删除;单位为秒,有效值范围60-1296000秒,也即1分钟到15天。

Q3:相比kafka有什么优势?

A3:跟kafka相比,各有侧重点,kafka更强调吞吐性能。CMQ强调是可靠传递,不丢。 CMQ的Kafka版本也即将推出,敬请期待。

Q4:CMQ消费方式是push还是pull?还是两者结合?

A4:当前queue的模式我们采取的是pull的方式。后续的topic的模式会有push,可以支持push到http端,短信,邮件,和queue。

Q5:哪些队列支持pubsub?

A5: 其实CMQ支持两种产品形态:queue和topic, 对于queue来说没有pubsub功能,topic有pubsub的能力也能把topic和queue串联起来使用,queue可以作为topic其中的一个sub方。

-END-

欢迎关注“互联网架构师”,我们分享最有价值的互联网技术干货文章,助力您成为有思想的全栈架构师,我们只聊互联网、只聊架构,不聊其他!打造最有价值的架构师圈子和社区。

本公众号覆盖中国主要首席架构师、高级架构师、CTO、技术总监、技术负责人等人 群。分享最有价值的架构思想和内容。打造中国互联网圈最有价值的架构师圈子。

  • 长按下方的二维码可以快速关注我们

  • 如想加群讨论学习,请点击右下角的“加群学习”菜单入群


腾讯云分布式高可靠消息队列CMQ架构最佳实践相关推荐

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

    在分布式大行其道的今天,我们在系统内部.平台之间广泛运用消息中间件进行数据交换及解耦.CMQ 是腾讯云内部自研基于的高可靠.强一致.可扩展分 布式消息队列,在腾讯内部包括微信手机 QQ 业务红包.腾讯 ...

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

    针对金融.交易.订单等对可靠性.可用性有较高要求的业务场景,本文分享如何通过CMQ消息队列实现高可用架构 作者:张浩         出处:腾云阁文章 ---------------------- 在 ...

  3. 实力分享,聚焦分布式高可用消息队列

    消息队列(Message Queue),是分布式系统中非常重要的组件,其通用的使用场景可以简单地描述为: 当不需要立即获得结果,但是并发量又需要进行控制的时候,差不多就是需要使用消息队列的时候. 消息 ...

  4. 消息队列 CMQ 七大功能实践案例

    背景 消息队列,在业务解耦.削峰填谷.流量控制.广播消息等场景下都有很好的应用,已经成为很多企业IT系统内部通信重要手段. 现有常用的开源消息中间件有RabbitMQ.Kafka.RocketMQ等, ...

  5. 腾讯云海量社交网络业务下的DevOps架构应用实践

    在DevOps的理念中,企业的IT价值链流转的速度越快,意味着企业的互联网产品的交付能力越强,这也意味着在同行业的竞争中,企业凭借IT能力的优势,能够收获更大的竞争优势.也因此,DevOps框架的落地 ...

  6. 京东云分布式链路追踪在金融场景的最佳实践

    微服务是近几年最流行的软件架构设计理念,和容器.devops一起构成了云原生的技术基础.微服务源于对产品快速交付的市场诉求,通过采取一系列的自动化测试.持续集成等敏捷开发实践,激活了组织效率,也增强了 ...

  7. 单集群10万节点 走进腾讯云分布式调度系统VStation

    云计算并非无中生有的概念,它将普通的单台PC计算能力通过分布式调度软件连接起来.其最核心的问题是如何把一百台.一千台.一万台机器高效地组织起来,灵活进行任务调度和管理,从而像使用单台机器一样方便地使用 ...

  8. 单机最大负载_分布式高可靠之负载均衡,今天看了你肯定会

    到目前为止,我已经为你介绍了分布式起源.分布式协调与同步.分布式资源管理与负载调度.分布式计算技术.分布式通信技术和分布式数据存储. 可以说,掌握了这些内容,基本上就掌握了分布式的关键技术.然而,只有 ...

  9. rockemq 发送延迟消息_58分布式消息队列WMB设计与实践

    背景 为了能够承载58业务的快速扩展及海量的用户访问,分布式系统已经成为公司一种主流架构设计.而消息队列是大型分布式系统中不可或缺的通信桥梁,在分布式系统解耦.异步通信.事件通知.流量削峰等业务场景中 ...

  10. harmonyos基于arm么,华为架构师解读:HarmonyOS低时延高可靠消息传输原理

    华为架构师解读:HarmonyOS低时延高可靠消息传输原理 [复制链接] 本文作者:zhangkesi,华为软件架构设计工程师 这是一篇HarmonyOS低时延高可靠消息传输原理的介绍,希望对你有所帮 ...

最新文章

  1. WdatePicker,js日期插件 ,时间相加
  2. 架构评审,技术总监怒了,丢给我 400 个架构案例,先研究透!
  3. autojs微博_js实现微博发布小功能
  4. mysql插入数据与删除重复记录的几个例子(收藏)
  5. 启动欢迎页面时,Android Studio设置全屏Activity
  6. postgresql select for update 多行加锁顺序_PostgreSQL和Mysql的MVCC实现机制的差异对比
  7. 【拓扑排序】排队-C++
  8. HTTP服务器恢复文件头,浅谈“Web服务器解析漏洞”
  9. Java——Map 集合
  10. 基于scap的服务器安全基线核查设计与实现
  11. JVM monitoring
  12. 大专适合学习php么_中专毕业上大专好还是出来工作?
  13. 怎樣制作线段动画_几何画板如何做动画,看完明白了
  14. 玩出来的33岁亿万富翁-畅游CEO王滔
  15. 20行代码制作字符画版小黄鸭表情包 | 文末送书抽奖结果
  16. ImageLoader 图片异步加载类库的使用
  17. 云​大数据和计算技术周报(第43期)
  18. 爬取虎扑社区,存入MongoDB数据库
  19. 正版手机应用导航,排排坐网站的初衷
  20. .NET Remoting 最简单示例

热门文章

  1. Oracle将Java EE移交Eclipse基金会
  2. Java 6 变量 代码块
  3. 利用bootstrap的modal组件自定义alert,confirm和modal对话框
  4. 启发式算法、寻路算法A*算法
  5. linux下led灯驱动程序
  6. 排土场、弃渣场和尾矿库的区别
  7. 如何正确处理HTTP 404错误页面
  8. ACS 4.2安装图解
  9. 「leetcode」617. 合并二叉树:【三种递归】【一种迭代】详解
  10. 微信微调助手WeChatTweak for mac(微信多开和防撤回工具)最新版