作者简介:ziza,2012年加入腾讯,一直专注于腾讯中间件产品的建设,主导参与了腾讯消息中间件CMQ、CKafka、MQ for IoT 等项目,见证了腾讯云消息服务从0到1的整个过程。目前专注于于分布式服务开发与治理平台TSF的建设。

大规模分布式系统的快速发展使得消息中间件已经成为系统间通信的核心手段。本文将对腾讯TEG基础架构部中间件团队研发的企业级消息中间件CMQ原理进行分享介绍。

背景介绍

可以使用消息队列的场景有很多,常见的有以下几种:

1.服务解耦:同步变异步,数据最终一致性;

2.削峰限流:类似“三峡大坝”,下游服务方被超过服务能力请求压垮;

3.广播订阅:发送方不关心谁订阅这个消息,只管发出来,拓展方便;

4.流式数据过滤:消费者通过类似SQL语句来筛选自己感兴趣的数据;

5.两阶段消息:通过两阶段消息与本地数据库事务相结合达到简单分布式事务。

中间件团队消息队列发展历程:

CMQ/CKafka/MQ for IoT本质上都属于分布式消息中间件,分布式消息系统的最大特点是可扩展性。核心理念是多个节点协同工作完成单个节点无法完成的任务,不允许出现单节点故障服务不可用(RTO)和数据丢失(RPO)情况。归根结底是解决CAP问题, CMQ作为金融级别服务要求数据高可靠强一致(CP), CKafka以大数据领域为主要服务对象,更偏重于AP,同时允许用户通过配置在CAP之间进行权衡,本文重点对CMQ进行介绍。

核心原理介绍

整体架构介绍

架构图

CMQ属于典型的三层架构,支持业界主流协议,业务可以选择HTTP/AMQP/MQTT等多种协议,适配层主要负责协议适配和路由控制,同时支撑系统水平弹性伸缩,后端Broker Set 提供消息持久化存储、转发以及基于消息的高阶功能,例如延时消息、事务消息、死信消息等;控制Server和管控平台负责对整个系统进行智能调度、故障处理、运营监控。

弹性伸缩:

分布式消息队列性能和消息堆积存储量理论上无上限,CMQ的路由控制Server 会根据存储Set的实际负载调整消息收发路由信息并同时适配层,适配层根据收到的路由指令调整数据最终流向后端那个Set,整个过程对使用者是透明的。

数据高可靠强一致:

CMQ 利用数据多副本存储来保证可靠性,通过Raft算法来保证副本间的数据强一致,数据生产过程大致如下:

以一个存储Set中3个节点为例,其中只有一个Master节点可以对外接收生产数据,另外两个节点作为Slave存在,同时Slave 会将收到的请求重定向到Master,详细过程如下:

1.Master 负责消息的生产消费请求,收到请求后先通过Raft一致性模块写Raft log到本地并同步给所有Slave节点;

2.Slave 收到Master发来的Raft log持久化到本地同时返回Master 成功信息;

3.Master 收到Set中过半节点的成功信息后将请求信息提交到mq 状态机;

4.Mq 状态机处理请求信息后返回用户成功;

可以看到对于生产数据CMQ会通过Raft算法确保Set中超过半数的节点已经完成存储持久化后才返回给用户发送成功,同时Raft 算法的选举原理保证数据对用户可见的强一致性,具体Raft算法不在此展开。

通过上述过程我们可以发现两个问题:

1.上述整个流程是串行的,Raft组内顺序执行上述流程,不能充分发挥节点性能;

2.相对Master节点,Slave做的事情更少,节点平时存在严重浪费;

为了提升QPS和机器利用率CMQ通过Multi-Raft将Set中的3个节点充分利用起来,多组Raft之前相互独立,Master 尽量打散分布在不同节点上。

在研发CMQ过程中,我们将其中使用到的Raft 算法进行抽象,沉淀成可独立使用的Raft算法库,目前已经在部门内部多个产品中使用,逐步完善后会进一步对外开源。

上面从设计与开发角度介绍了CMQ一致性原理,但是如何验证开发出来的CMQ是符合线性一致性的呢?为此我们参考业界知名的分布式系统完备性工具jepsen设计开发了自己的验证系统,原理如下:

1.部署要测试的集群;

2.ControlNode执行测试程序

  • 启动集群

  • 生产执行序列

  • 5个client线程并发运行执行序列,同时通过Nemesis线程进行错误及异常注入测试,6个线程将执行过程log 记录到history。

3. Module是根据系统行为提前定义好的正确性验证模型,Checker结合Module分析history输出测试报告。

高性能优化:

Raft 算法中存在以下两个比较耗时的操作:

1.Master每收到一个请求都向所有Slave各发起一次网络IO, Slave处理成功后回复Master成功。

2.Master 和Slave 还需要对收到的请求同步刷盘

对上述两个步骤进行分解:

3.fsync_raft_log时间取决于磁盘性能,raft_log网络传输时间取决于网络RTT。由此可见这两个值是硬件相关的,因此我们在消息个数、时间两个维度来尽可能合并消息,做到批量发送raft_log 和批量刷盘来提高QPS。

可用性保证:

CMQ具备节点、Set、园区三级高可用保障机制,业务可根据实际需求来按需选择。

节点可用性:

如果Set中的单个Slave 发生故障,由于此时Set满足大多数节点可用,得益于Raft算法使得故障对业务是完全透明的;如果是Master 发生故障,此时Raft 算法会自动发起选举,符合条件的Slave 自动提升为Master, 整个过程是秒级别的,由于存在重试逻辑,所以绝大部分情况下对业务影响也是透明的。

Set 级别可用性:

很不幸,假设一个Set中的3个节点中的两个节点同时发生了故障,此时按照Raft算法要求的大多数节点都同意才能提交请求到MQ状态机的原则,当前Set 是不可用的。此时CMQ通过双Set来保障可用性,大致原理如下:

业务在申请使用消息队列时CMQ会在两个Set上分别建立队列元数据,正常情况下只有一个Set 对外服务,另外一个Set standby;当一个Set 不可用时间超过一定时间,消息流会自动切换到之前Standby的Set上。为了提高Set使用率,Standby 队列并没有独占Set,而是分布在不同的Set 之上。对于存留在故障Set上的还未来得及消费的数据需要故障恢复后才能正常消费。

数据中心级别可用性:

金融业务在应用层都有多中心多活的要求,防止数据中心故障后导致整个服务不可用。CMQ通过插件的方式对两个数据中心的消息服务进行异步同步。当一个数据中心故障时任然存在少量未来的及同步的数据丢失的情况,此时需要通过log 或者对账来恢复数据。

消息Log Trace

消息中间件日常运营中最常见的一个问题是如何证明系统没有丢消息?为此CMQ提供了一套消息trace 系统。Agent 将每条消息的ID、生产者、消费者信息都上报到log 存储系统,业务对于有疑问的消息可以在控制台上直接查询,就能看到消息的整个流转消费情况。

开源竞品对比

业界高可靠消息中间件主要以RabbitMQ为主,下面对CMQ和RabbitMQ进行分析对比。

RabbitMQ 集群镜像模式节点间采用自研的可靠多播(Guaranteed Multicast)算法来同步数据,GM可靠多播将集群中所有节点组成一个环。Log 复制依次从 Master 向后继节点传播,当 Master 再次收到该请求时,发出确认消息在环中传播,直至 Master再次收到该确认消息,表明Log 在环中所有节点同步完成。

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

相同条件下对CMQ 和RabbitMQ 进行性能测试,测试场景如下:三台同样配置的机器组成一个集群,CMQ、RabbitMQ 均配置为镜像队列,数据均在三台机器上同步。 CMQ 和 RabbitMQ 都开启生产、消费消息确认机制。测试中的生产消息大小为1KB。

测试环境

环境说明

CPU

24核

内存

64G

磁盘

SATA

网卡

10G

Linux版本

2.6.32.43

RabbitMQ版本

3.6.2

Erlang版本

18.3

测试数据如下:

QPS对比

仅生产

仅消费

同时生产/消费

CMQ

生产:6.8w/s

消费:9w/s

生产:3.6w/s
 消费:3.6w/s

RabbitMQ

生产:1.25w/s

消费:2.6w/s

生产:0.85w/s
 消费:0.85w/s

在高可靠场景中,CMQ 吞吐量优于 RabbitMQ的四倍以上。

总结

本文主要腾讯基础架构部消息中间件发展历程进行简要介绍,重点对金融级消息中间件CMQ核心原理进行分享,除此之外,中间件团队针对大数据领域常用的kafka进行优化改进推出了CKafka,在相同条件下小于4KB的情况下生产性能是开源社区的两倍以上;针对物联网研发的IoT Hub中的MQ引擎,完全兼容MQTT3.1协议,配合IoT Gate Way 可以轻松支持上亿并发连接,欢迎大家体验使用,也期待更多技术达人加入中间件团队。

专题介绍

ArchSummit全球架构师峰会是InfoQ中国团队推出的面向高端技术管理者、架构师的技术大会,参会者数量1000+。其中,出品人及演讲嘉宾中高级技术专家比例占79%,90%拥有10年以上开发经验。本次“TEGer在全球架构师峰会”专题将带来TEG人在会上的系列主题分享。

作者简介:ziza,2012年加入腾讯,一直专注于腾讯中间件产品的建设,主导参与了腾讯消息中间件CMQ、CKafka、MQ for IoT 等项目,见证了腾讯云消息服务从0到1的整个过程。目前专注于于分布式服务开发与治理平台TSF的建设。


大规模分布式系统的快速发展使得消息中间件已经成为系统间通信的核心手段。本文将对腾讯TEG基础架构部中间件团队研发的企业级消息中间件CMQ原理进行分享介绍。

背景介绍

可以使用消息队列的场景有很多,常见的有以下几种:

1.服务解耦:同步变异步,数据最终一致性;

2.削峰限流:类似“三峡大坝”,下游服务方被超过服务能力请求压垮;

3.广播订阅:发送方不关心谁订阅这个消息,只管发出来,拓展方便;

4.流式数据过滤:消费者通过类似SQL语句来筛选自己感兴趣的数据;

5.两阶段消息:通过两阶段消息与本地数据库事务相结合达到简单分布式事务。

中间件团队消息队列发展历程:

CMQ/CKafka/MQ for IoT本质上都属于分布式消息中间件,分布式消息系统的最大特点是可扩展性。核心理念是多个节点协同工作完成单个节点无法完成的任务,不允许出现单节点故障服务不可用(RTO)和数据丢失(RPO)情况。归根结底是解决CAP问题, CMQ作为金融级别服务要求数据高可靠强一致(CP), CKafka以大数据领域为主要服务对象,更偏重于AP,同时允许用户通过配置在CAP之间进行权衡,本文重点对CMQ进行介绍。

核心原理介绍

整体架构介绍

架构图

CMQ属于典型的三层架构,支持业界主流协议,业务可以选择HTTP/AMQP/MQTT等多种协议,适配层主要负责协议适配和路由控制,同时支撑系统水平弹性伸缩,后端Broker Set 提供消息持久化存储、转发以及基于消息的高阶功能,例如延时消息、事务消息、死信消息等;控制Server和管控平台负责对整个系统进行智能调度、故障处理、运营监控。

弹性伸缩:

分布式消息队列性能和消息堆积存储量理论上无上限,CMQ的路由控制Server 会根据存储Set的实际负载调整消息收发路由信息并同时适配层,适配层根据收到的路由指令调整数据最终流向后端那个Set,整个过程对使用者是透明的。

数据高可靠强一致:

CMQ 利用数据多副本存储来保证可靠性,通过Raft算法来保证副本间的数据强一致,数据生产过程大致如下:

以一个存储Set中3个节点为例,其中只有一个Master节点可以对外接收生产数据,另外两个节点作为Slave存在,同时Slave 会将收到的请求重定向到Master,详细过程如下:

1.Master 负责消息的生产消费请求,收到请求后先通过Raft一致性模块写Raft log到本地并同步给所有Slave节点;

2.Slave 收到Master发来的Raft log持久化到本地同时返回Master 成功信息;

3.Master 收到Set中过半节点的成功信息后将请求信息提交到mq 状态机;

4.Mq 状态机处理请求信息后返回用户成功;

可以看到对于生产数据CMQ会通过Raft算法确保Set中超过半数的节点已经完成存储持久化后才返回给用户发送成功,同时Raft 算法的选举原理保证数据对用户可见的强一致性,具体Raft算法不在此展开。

通过上述过程我们可以发现两个问题:

1.上述整个流程是串行的,Raft组内顺序执行上述流程,不能充分发挥节点性能;

2.相对Master节点,Slave做的事情更少,节点平时存在严重浪费;

为了提升QPS和机器利用率CMQ通过Multi-Raft将Set中的3个节点充分利用起来,多组Raft之前相互独立,Master 尽量打散分布在不同节点上。

在研发CMQ过程中,我们将其中使用到的Raft 算法进行抽象,沉淀成可独立使用的Raft算法库,目前已经在部门内部多个产品中使用,逐步完善后会进一步对外开源。

上面从设计与开发角度介绍了CMQ一致性原理,但是如何验证开发出来的CMQ是符合线性一致性的呢?为此我们参考业界知名的分布式系统完备性工具jepsen设计开发了自己的验证系统,原理如下:

1.部署要测试的集群;

2.ControlNode执行测试程序

  • 启动集群

  • 生产执行序列

  • 5个client线程并发运行执行序列,同时通过Nemesis线程进行错误及异常注入测试,6个线程将执行过程log 记录到history。

3. Module是根据系统行为提前定义好的正确性验证模型,Checker结合Module分析history输出测试报告。

高性能优化:

Raft 算法中存在以下两个比较耗时的操作:

1.Master每收到一个请求都向所有Slave各发起一次网络IO, Slave处理成功后回复Master成功。

2.Master 和Slave 还需要对收到的请求同步刷盘

对上述两个步骤进行分解:

3.fsync_raft_log时间取决于磁盘性能,raft_log网络传输时间取决于网络RTT。由此可见这两个值是硬件相关的,因此我们在消息个数、时间两个维度来尽可能合并消息,做到批量发送raft_log 和批量刷盘来提高QPS。

可用性保证:

CMQ具备节点、Set、园区三级高可用保障机制,业务可根据实际需求来按需选择。

节点可用性:

如果Set中的单个Slave 发生故障,由于此时Set满足大多数节点可用,得益于Raft算法使得故障对业务是完全透明的;如果是Master 发生故障,此时Raft 算法会自动发起选举,符合条件的Slave 自动提升为Master, 整个过程是秒级别的,由于存在重试逻辑,所以绝大部分情况下对业务影响也是透明的。

Set 级别可用性:

很不幸,假设一个Set中的3个节点中的两个节点同时发生了故障,此时按照Raft算法要求的大多数节点都同意才能提交请求到MQ状态机的原则,当前Set 是不可用的。此时CMQ通过双Set来保障可用性,大致原理如下:

业务在申请使用消息队列时CMQ会在两个Set上分别建立队列元数据,正常情况下只有一个Set 对外服务,另外一个Set standby;当一个Set 不可用时间超过一定时间,消息流会自动切换到之前Standby的Set上。为了提高Set使用率,Standby 队列并没有独占Set,而是分布在不同的Set 之上。对于存留在故障Set上的还未来得及消费的数据需要故障恢复后才能正常消费。

数据中心级别可用性:

金融业务在应用层都有多中心多活的要求,防止数据中心故障后导致整个服务不可用。CMQ通过插件的方式对两个数据中心的消息服务进行异步同步。当一个数据中心故障时任然存在少量未来的及同步的数据丢失的情况,此时需要通过log 或者对账来恢复数据。

消息Log Trace

消息中间件日常运营中最常见的一个问题是如何证明系统没有丢消息?为此CMQ提供了一套消息trace 系统。Agent 将每条消息的ID、生产者、消费者信息都上报到log 存储系统,业务对于有疑问的消息可以在控制台上直接查询,就能看到消息的整个流转消费情况。

开源竞品对比

业界高可靠消息中间件主要以RabbitMQ为主,下面对CMQ和RabbitMQ进行分析对比。

RabbitMQ 集群镜像模式节点间采用自研的可靠多播(Guaranteed Multicast)算法来同步数据,GM可靠多播将集群中所有节点组成一个环。Log 复制依次从 Master 向后继节点传播,当 Master 再次收到该请求时,发出确认消息在环中传播,直至 Master再次收到该确认消息,表明Log 在环中所有节点同步完成。

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

相同条件下对CMQ 和RabbitMQ 进行性能测试,测试场景如下:三台同样配置的机器组成一个集群,CMQ、RabbitMQ 均配置为镜像队列,数据均在三台机器上同步。 CMQ 和 RabbitMQ 都开启生产、消费消息确认机制。测试中的生产消息大小为1KB。

测试环境

环境说明

CPU

24核

内存

64G

磁盘

SATA

网卡

10G

Linux版本

2.6.32.43

RabbitMQ版本

3.6.2

Erlang版本

18.3

测试数据如下:

QPS对比

仅生产

仅消费

同时生产/消费

CMQ

生产:6.8w/s

消费:9w/s

生产:3.6w/s
 消费:3.6w/s

RabbitMQ

生产:1.25w/s

消费:2.6w/s

生产:0.85w/s
 消费:0.85w/s

在高可靠场景中,CMQ 吞吐量优于 RabbitMQ的四倍以上。

总结

本文主要腾讯基础架构部消息中间件发展历程进行简要介绍,重点对金融级消息中间件CMQ核心原理进行分享,除此之外,中间件团队针对大数据领域常用的kafka进行优化改进推出了CKafka,在相同条件下小于4KB的情况下生产性能是开源社区的两倍以上;针对物联网研发的IoT Hub中的MQ引擎,完全兼容MQTT3.1协议,配合IoT Gate Way 可以轻松支持上亿并发连接,欢迎大家体验使用,也期待更多技术达人加入中间件团队。

专题介绍

ArchSummit全球架构师峰会是InfoQ中国团队推出的面向高端技术管理者、架构师的技术大会,参会者数量1000+。其中,出品人及演讲嘉宾中高级技术专家比例占79%,90%拥有10年以上开发经验。本次“TEGer在全球架构师峰会”专题将带来TEG人在会上的系列主题分享。

腾讯企业级消息中间件CMQ技术解密相关推荐

  1. 腾讯技术工程 | 腾讯企业级消息中间件CMQ技术解密

    作者简介:ziza,2012年加入腾讯,一直专注于腾讯中间件产品的建设,主导参与了腾讯消息中间件CMQ.CKafka.MQ for IoT 等项目,见证了腾讯云消息服务从0到1的整个过程.目前专注于于 ...

  2. 腾讯万亿级 Elasticsearch 技术解密

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者: johngqjiang,腾讯 TEG 云架构平台部研发工程 ...

  3. 听腾讯 TEG 大佬谈腾讯万亿级 Elasticsearch 技术解密

    作者:johngqjiang,腾讯 TEG 云架构平台部研发工程师 Elasticsearch(ES)作为开源首选的分布式搜索分析引擎,通过一套系统轻松满足用户的日志实时分析.全文检索.结构化数据分析 ...

  4. 嘉年华回顾丨李海翔带你解密腾讯TDSQL数据库的技术与未来

    2020年数据技术嘉年华即将进入1个月倒计时,相信大家期待值也越来越高.数据技术嘉年华组委会在此精心为大家准备了"嘉年华回顾",挑选往届大会中热门的演讲.小编带大家回顾往届的高光时 ...

  5. 十年京东,十年技术发展—畅读《京东技术解密》

    <京东技术解密>试读章节共71页,我花了两天时间仔细读完,读了过后感到意犹未尽,非常想一口气把整本读完,然而只能将试读章节反复读了好几遍,收获颇多,遂有此文,借此总结京东十年来的技术变迁和 ...

  6. 亿级商品详情页架构演进技术解密 | 高可用架构系列

    亿级商品详情页架构演进技术解密 | 高可用架构系列 --http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=210272034&i ...

  7. 让餐厅放心的云服务-雅座CRM技术解密

     让餐厅放心的云服务-雅座CRM技术解密 发表于2015-07-02 16:03| 2036次阅读| 来源CSDN| 4 条评论| 作者杨砚 云计算SaaS雅座CRM width="22 ...

  8. 【大数据】企业级大数据技术体系概述

    目录 产生背景 常见应用场景 企业级大数据技术框架 数据收集层 数据存储层 资源管理与服务协调层 计算引擎层 数据分析层 数据可视层 企业级大数据技术实现方案 Google 大数据技术栈 Hadoop ...

  9. 微信团队分享:微信每日亿次实时音视频聊天背后的技术解密

    本文内容整理自腾讯专家研究员 & 微信视频技术负责人谷沉沉在 2017 ArchSummit 全球架构师峰会上的技术分享. 1.前言 2012 年 7 月,微信 4.2 版本首次加入了实时音视 ...

最新文章

  1. 使用rancher对Docker容器服务升级
  2. mysql 取出20条数据_“取出数据表中第10条到第20条记录”的sql语句+select top 使用方法...
  3. Matplotlib实例教程(六)直方图
  4. JSR 303约束规则
  5. python 获取html js 变量_Python爬虫与反反爬虫实践
  6. 阿里云总裁胡晓明:保护客户数据隐私是阿里云第一原则
  7. 每日英语:Why is Ye Shiwen’s Swim “Disturbing”?
  8. 根据进程名杀掉jps中的进程名
  9. 【渝粤题库】陕西师范大学151203 初级会计学作业(笔试题型)
  10. java数组与以逗号分隔开的字符串的相互转换
  11. 企业数据分析,搞定这3个重点事半功倍!
  12. 【转自CSDN论坛】行业软件的利润从哪里来?
  13. Kubernetes RBAC 详解
  14. STP中各算法接口开销(COST)计算方式
  15. mysql使用mybatis删除不生效_解决myBatis中删除条件的拼接问题
  16. Java - JSP和Servlet是什么关系?
  17. 语音机器人在人工智能领域的发展
  18. PowerDesigner书签(03)显示comment字段注释内容
  19. 关于cocoapods遇到xxxx file not found和No such module 'XXX'的问题
  20. 非线性优化中的KTT条件(知乎文章的理解)

热门文章

  1. finally块的问题(finally block does not complete normally) (转)
  2. aspcms各版本漏洞0day集合
  3. harris角点检测的学习
  4. HDU - 4348 To the moon(主席树区间更新-标记永久化)
  5. CodeForces - 1343E Weights Distributing(最短路)
  6. DeepSORT多目标跟踪算法
  7. 动态规划算法-02矿工挖矿问题
  8. 主定理(master theorem)学习小记
  9. [Windows驱动开发](一)序言
  10. C++ COM编程之什么是接口