在分布式大行其道的今天,我们在系统内部、平台之间广泛运用消息中间件进行数据交换及解耦。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. 【转】 如何提高自己的acm个人能力

    2011-05-17 21:26 1429人阅读 评论(0) 收藏 举报 算法网络blog八卦游戏读书 转载自 简单de数字 最终编辑 fading_code by   zfy0701 本来以为HNU ...

  2. 阿里云服务器windows系统C盘一键清理脚本

    @ECHO OFF @echo @echo @echo 清理几个比较多垃圾文件的地方 DEL /F /S /Q "C:\WINDOWS\PCHealth\ERRORREP\QSIGNOFF\ ...

  3. nodejs 中使用 mocha + should + jscoverage 生成 单元测试覆盖率报告

    最近一直在做nodejs,而关于js的单元测试覆盖率网上资料比较少而且吧比较零散,我从网上找来一些资料整理一下分析给大家,希望大家可以少走弯路. 首先我是从windows环境下测试的,用到的工具有 m ...

  4. JS日期时间加减实现

    首先,上代码 var diffDate = function(date, diff) { return new Date( Date.UTC( date.getUTCFullYear(), date. ...

  5. ES1:Windows下安装ElasticSearch

    ElasticSearch(简称ES)是一个基于Lucene的分布式全文搜索服务器,本随笔演示在Windows安装ElasticSearch和用于管理ES的Head插件. ElasticSearch官 ...

  6. TSQL编程

    1.索引 唯一键/主键添加索引,设计界面,在任何一列前右键--索引/键--点击进入添加某一列为索引 2.视图 视图就是我们查询出来的虚拟表创建视图:create view 视图名  as  SQL查询 ...

  7. Kafka 0.10 KafkaConsumer流程简述

    ConsumerConfig.scala 储存Consumer的配置 按照我的理解,0.10的Kafka没有专门的SimpleConsumer,仍然是沿用0.8版本的. 1.从poll开始 消费的规则 ...

  8. Ubuntu 制作U盘启动盘

    部门需要一台Linux系统远程共享服务器,需要一个启动盘安装.但是由于公司windows 系统都安装了保安软件,而且软件的使用也是有限制的.所以不能使用UltraISO 这类软件制作U盘启动盘.还好部 ...

  9. vs调试时底部输出调试信息“无法查找或打开 PDB 文件”解决办法

    用VS调试程序时,有时会在VS底部的"输出"框中提示"无法查找或打开 PDB 文件".这该怎么解决呢? 下面,我们以VS2013为例,来教大家解决办法. 工具/ ...

  10. C#文本框允许使用ctrl+A

    C#文本框中默认是不允许使用全选的.可以通过以下事件完成: private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.C ...