在分布式大行其道的今天,我们在系统内部、平台之间广泛运用消息中间件进行数据交换及解耦。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,很好的满足了大数据场景,具体原理请留意后续文章介绍。

相关推荐

腾讯云CMQ消息队列在Windows环境下的使用

腾讯云CMQ消息队列测试


版权说明:本人作者张浩,转载请注明文章出处,获取更多云计算技术干货

原文阅读请前往腾讯云技术社区

知乎关注腾讯云

关注官方微信公众号:腾讯云技术社区( QcloudCommunity)

腾讯云分布式高可靠消息队列服务CMQ架构的更多相关文章

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

    版权声明:本文由张浩原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/126 来源:腾云阁 https://www.qclou ...

  2. [转帖]单集群10万节点 走进腾讯云分布式调度系统VStation

    单集群10万节点 走进腾讯云分布式调度系统VStation https://www.sohu.com/a/227223696_355140 2018-04-04 08:18 云计算并非无中生有的概念, ...

  3. .Net Core with 微服务 - 分布式事务 - 可靠消息最终一致性

    前面我们讲了分布式事务的2PC.3PC , TCC 的原理.这些事务其实都在尽力的模拟数据库的事务,我们可以简单的认为他们是一个同步行的事务.特别是 2PC,3PC 他们完全利用数据库的事务能力,在一 ...

  4. 阿里云RocketMQ定时/延迟消息队列实现

    新的阅读体验:http://www.zhouhong.icu/post/157 一.业务需求 需要实现一个提前二十分钟通知用户去做某件事的一个业务,拿到这个业务首先想到的最简单得方法就是使用Redis ...

  5. 【阿里云产品公测】消息队列服务MQS java SDK 机器人应用初体验

    [阿里云产品公测]消息队列服务MQS java SDK 机器人应用初体验 作者:阿里云用户啊里新人   初体验 之 测评环境 由于MQS支持外网访问,因此我在本地做了一些简单测试(可能有些业余),之后 ...

  6. Sping Boot入门到实战之实战篇(一):实现自定义Spring Boot Starter——阿里云消息队列服务Starter

    在 Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置 这篇中,我们知道Spring Boot自动化配置的实现,主要由如下几部分完成: @EnableAutoConfigu ...

  7. Java高并发--消息队列

    Java高并发--消息队列 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 举个例子:在购物商城下单后,希望购买者能收到短信或者邮件通知.有一种做法时在下单逻辑执行后调 ...

  8. NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例

    一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...

  9. Redis作为消息队列服务场景应用案例

    NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例   一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更 ...

随机推荐

  1. Xcode 设置文件生成时的模板

    1. 目的 设置 Xcode 生成的文件的格式,如姓名.公司等. 2. 步骤 2.1. 找到文件 step 1. 右键Xcode图标 step 2. 显示包内容 step 3. 找到目录 /Conte ...

  2. Javascript数据类型共有六种

    Javascript数据类型共有六种 /* var box; alert(typeof box); // box是Undefined类型,值是undefined,类型返回的字符串是undefined ...

  3. C#综合揭秘——细说进程、应用程序域与上下文之间的关系

    引言 本文主要是介绍进程(Process).应用程序域(AppDomain)..NET上下文(Context)的概念与操作.虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提高 ...

  4. 利用Flare3D和Stage3D创建3D

    Flare3D 是一款功能强大的引擎,它使得 Flash 中的 3D 内容管理变得更为简便. 它的设计宗旨是提供一个完美的开发工作流程,以便你能够获得事半功倍的效果. 本教程侧重讨论在 Flash 中 ...

  5. 玩转微信小程序

    原文链接 2007 年 1 月 9 号,苹果一代在功能机盛行的年代中出世. 2017 年 1 月 9 号,微信小程序在重型app风靡的压力下上线. 苹果的出世掀起了互联网一波又一波的浪潮,而微信小程序 ...

  6. S2SH框架整合(注解)Struts2+Spring+Hibernate+MySql

    整合简介 Struts2+Spring4+hibernate4整合,Maven管理jar包,Eclipse工具.注解方式 架构截图   1.Spring整合Hibernate 1.1.创建Hibern ...

  7. MyBatis 源码分析——SqlSession接口和Executor类

    mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用.可以说SqlSession接口实例是开发过程中打交道最多的一个类.即是DefaultSqlSession类.如果笔者记得 ...

  8. Professional C# 6 and .NET Core 1.0 - What’s New in C# 6

    本文为转载,学习研究 What's New in C# 6 With C# 6 a new C# compiler is available. It's not only that a source ...

  9. 关于Node.js后端架构的一点后知后觉

    前言 上周有幸和淘宝前端团队的七念老师做了一些NodeJS方面上的交流(实际情况其实是他电话面试了我╮(╯-╰)╭),我们主要聊到了我参与维护的一个线上NodeJS服务,关于它的现状和当下的不足.他向 ...

  10. win10更新时遇到错误0x80070002的正确处理方法

    win10更新Flash Player.或者在  “启用或关闭windows功能” 经常出现提示错误0x80070002,这要怎么解决呢?这里介绍下正确的错误代码0x80070002解决办法. 严肃提 ...