腾小云导读
作者是腾讯 TDMQ 初创团队的成员,在多年的事务中台的实践中,也频繁地运用到了 MQ,比如最常见的音讯推送,失常信息的重试等等,对音讯队伍有深刻的了解。此篇文章,作者会站在时刻维度解说这二十年每款 MQ 诞生的布景以及处理了何种问题,让你可以更加清晰地了解到 MQ 的底层逻辑,帮忙你学习往后可能会呈现的新架构。欢迎阅读~
目录
1 音讯队伍展开进程
1.1 第一阶段:解耦合
1.2 第二阶段:吞吐量与一起性
1.3 第三阶段:途径化
2 音讯队伍的通用架构及根本概念
2.1 主题、出产者、顾客
2.2 分区
3 干流音讯队伍存储剖析
3.1 Kafka
3.2 RocketMQ
3.3 pulsar
4 总结
01、音讯队伍展开进程
2003至今有许多优异的音讯队伍诞生,其间就有被我们所熟知的 Kafka、RocketMQ,以及后起之秀 pulsar。首要我们先来了解一下每一时期音讯队伍诞生的布景以及要处理的核心问题是什么?
如上图,我把音讯队伍的展开切分成了三个大的阶段。
1.1 第一阶段:解耦合
从2003年到2010年之前,03年可以说核算机软件行业刚刚兴起,处理系统间强耦合变成了程序规划的一大难题,这一阶段以 activemq 和 rabbitmq 为主的音讯队伍致力于处理系统间解耦合和一些异步化的操作问题,这也是全部音讯队伍被运用的最多功用之一。
1.2 第二阶段:吞吐量与一起性
在2010年到2012年期间,大数据年代正式到来,实时核算的需求越来越高,数据规模也越来越大。因为传统音讯队伍已无法满意大数据的需求,音讯队伍规划的关键因素逐步转向为吞吐量和并发程度。在这一布景下,Kafka 应运而生,并在日志搜集和数据通道范畴占据了重要方位。
但是,跟着阿里电商事务的兴起,Kafka 在可靠性、一起性、次第音讯、事务音讯支撑等方面现已无法满意阿里电商场景的需求。因此,RocketMQ 诞生了,阿里在自研音讯队伍的进程中吸收了 Kafka 的许多规划理念,如次第写盘、零拷贝、end-to-end 紧缩办法,并在此基础上处理了 Kafka 的一些痛点问题,比如强依托 Zookeeper。后来,阿里将 RocketMQ 捐赠给了 Apache,并毕竟成为了 Apache RocketMQ。
1.3 第三阶段:途径化
“没有途径的产品是没用的,再准确一点,去途径化的产品总是被途径化的产品所替代” 这句话并不是我说的,而是来自一篇来自2011年的文章《steve 对亚马逊和 google 的吐槽》。
2012今后,跟着云核算、k8s、容器化等新式的技术兴起,怎样把根本底层技术才干途径化成为了许多公司的攻坚方向,阿里云、腾讯云、华为云的出场都证明了这点,在这种大布景下,Pulasr 诞生了。
yahoo起先发起 pulsar 项目是为了处理以下三个问题:
公司内部多团队重复制作轮子。 当时干流 MQ 的租户阻隔机制都支撑得不是很好。 数据搬家、恢复、缺点转移个个都是头疼的问题,音讯队伍运维本钱极高。 |
---|
这三个问题的答案都指向了一个方向:途径化。
02、音讯队伍的通用架构及根本概念
第一节我们从时刻线上介绍了干流的音讯队伍发生的布景,这一末节我们先从生活场景入手,了解音讯队伍最最根本的概念。
2.1 主题、出产者、顾客
场景:食堂吃饭。
我们可以把吃饭抽象成三步:
第一步:当你进入饭堂,首要你想的是我今日吃什么,挑选适合的档口,比如有米饭、有面、有麻辣香锅。这儿的米饭、面、麻辣香锅就是 topic 主题的概念。 第二步:当你挑选了面档,下一步就是排队,排队默许的就是站在一个部队的队尾,你参加部队的这一进程统称为入队,此时关于 MQ 则是成功出产了一条音讯。 第三步:通过了等候,总算排到了你,并把饭菜成功拿走。这个进程称为出队,档口相当于顾客,消费了“你”这一条信息。 |
---|
通过这个比如,你可以很好地了解,主题(topic)、出产者(producer)、顾客(consumer)这三个概念。
2.2 分区(partition)
分区概念可以帮忙我们在核算机国际里关于实在国际的抽象层面更好了解,关于了解音讯队伍极其重要。假设你申请过云上的音讯队伍,途径会让你填写一个分区大小的参数选项,那分区到底是什么意思,我们接着向下看。
我们仍是举学校食堂的比如,假设有一天学校大面积扩招,一下次多来了一万名学生,幻想一下,你每次去食堂吃面,排上喜欢吃的东西,估量要等个一个小时,学校必定也会想办法,很简略,就是把一个档口变成多个档口,对食堂进行扩建(扩容)。扩容前,卖面的档口只需一个,人多人少你都要排队。扩容后,你只需挑选(路由)一个人少的档口就 ok。这儿多个部队就是多个分区。当了解了分区,就可以很好了解:分区使得音讯队伍的写吞吐量有了横向扩展的才干,这儿也是 Kafka 为什么可以高吞吐的本质原因。
03、干流音讯队伍存储剖析
特性与功用是存储结构的一种显化体现。特性是表象,存储才是本质。我们要搞清楚每款音讯的特性,很有必要去了解它们在架构上的规划。这章节,我们先会去介绍 Kafka、RocketMQ、pulsar 各自的架构特色,然后再去对比架构上的不同带来了什么功用上的不同。
3.1 Kafka
- 架构图
关于 Kafka 架构,需求首要阐明的一点,Kafka 的服务节点并没有主从之分,主从的概念是针对 topic 下的某个 partition。关于存储的单位,微观上来说就是分区,通过分区散落在各个节点的办法不同,可以组合出各种各样的架构图。以下是出产者数量为1、顾客数量为1、分区数为2、副本数为3、服务节点数为3的架构图。图中两块绿色图像分别为 topic1-partition1 分区和 topic1-partition2 分区,浅绿色方块为他们的副本,此时关于服务节点1, topic1-partition1 就是主节点,服务节点2和3为从节点;但是关于服务节点2,topic1-partition2有是主分区,服务节点1和服务节点3变成了从节点。讲到这儿,想必你现已对主从架构有了一个进一步地了解。
我们先来看看音讯队伍的大致作业流程。
出产者 、顾客首要会和元数据中心(zookeeper)建立衔接、并坚持心跳,获取服务的实况以及路由信息。 音讯会被 send 到 topic 下的任一分区中(这儿通过算法会确保每个 topic 下的分区尽可能均匀),一般情况下,信息需求落盘才可以给上游回来 ack,确保了宕机后的信息完整性。在信息写成功主分区后,系统会根据战略,挑选同步拷贝仍是异步拷贝,以确保单节点缺点时的信息完整性。 顾客此时开端作业,拉取响应的信息,并回来 ack,此时 offset+1。 |
---|
- 好的规划
下来我们来了解一下 Kafka 架构优异的规划理念。
磁盘次第写盘: Kafka 在底层规划上强依托于文件系统(一个分区对应一个文件系统),本质上是根据磁盘存储的音讯队伍,在我们固有印象中磁盘的读写速度是非常慢的,慢的原因是在读写的进程中全部的进程都在抢占“磁头”这把锁,磁头在读写之前需求将其移动到适合的方位,这个“移动”极其耗费时刻,这也就是磁盘慢的原因,但是怎样不用移动磁头呢,次第写盘就诞生了。
Kafka 音讯存储在分区中,每个分区对应一组连续的物理空间。新音讯追加到磁盘文件结尾。顾客按次第拉取分区数据消费。Kafka 的读写是次第的,可以高效地运用 PageCache,处理磁盘读写的功用问题。
以下是一张磁盘、ssd、内存的写入功用对比图,我们可以明显地看出次第写入的功用快于 ssd 的次第/随机写,与内存的次第/随机功用也相差不大,这一特性非常重要,许多组件的底层存储规划都会用到这点,了解好这点对了解音讯队伍尤为重要。(举荐阅读《 The Pathologies of Big Data 》)
- 一些问题
任何事物都有两面性,次第写盘的规划也带来一些其他的问题。
topic 数量不能过大: Kafka 的整体功用受到了 topic 数量的约束,这和底层的存储有密不可分的联系,我们上文讲过,当音讯来的时分,底层数据运用追加写入的办法,次第写盘,使得整体的读写功用大大前进,但这并不能代表全部情况,当我们 topic 数量从几个变成上千个的时分,情况就有所不同了,如下图所示。
以上左图代表了队伍中自始至终的信息为:topic1、topic1、topic1、topic2,在这种情况下,很好地运用了次第写盘的特性,磁头不用去移动,但是关于右边图的情况,队伍中自始至终的信息为:topic1、topic2、topic3、topic4,当队伍中的信息变得很涣散的时分,我们会发现,好像没有办法运用磁盘的次第写盘特性,因为每次写完一种信息,磁头都需求进行移动,读到这儿,你就很好了解,为什么当 topic 数量很大时,Kafka 的功用会急剧下降了。
当然会有小伙伴问,没有其他办法了吗,当然有。我们可以把存储换成速度更快 ssd 或许针对每一个分区都搞一块磁盘,当然这都是钱!许多时分,系统的6个9、7个9,并不是有多好的规划,而是用真金白银换来的,这是一种 trade off,失掉什么得到什么,我们可以对比看看自己的系统,大多数情况是什么换什么。
3.2 RocketMQ
- 架构图
以下是 RocketMQ 双主双从的架构,对比 Kafka,RocketMQ 有两点很大的不同:
元数据管理系统,从 zookeeper 变成了轻量级的独立服务集群。 服务节点变为多主多从架构。 |
---|
- zookeeper 与 namesrv
Kafka 运用的 zookeeper 是 cp 强一起架构的一种,其内部运用 zab 算法,进行信息同步和容灾,在信息量较小的情况下,功用较好,当信息交互变多,因为同步带来的功用损耗加大,功用和吞吐量下降。假设 zookeeper 宕机,会导致整个集群的不可用,关于一些买卖场景,这是不可承受的,为了前进大数据场景下,音讯发现系统的可用性与整体的吞吐量,比较 zookeeper,RocketMQ 挑选了轻量级的独立服务器 namesrv,其有以下特色:
运用简略的 k/v 结构保存信息。 支撑集群方式,每个 namesrv 相互独立,不进行任何通讯。 数据都保存在内存当中,broker 的注册进程通过循环遍历全部 namesrv 进行注册。 |
---|
- 部分次第写(Kafka) 与彻底次第写(RocketMQ)
Kafka 写流程中会把不同分区写入对应的文件系统中,其规划理念确保了 Kafka 优异的水平扩容才干。RocketMQ 的规划理念则是寻求极致的音讯写,将全部的 topic 音讯存储在同一个文件中,确保全部音讯发送时按次第写文件,尽最大才干确保音讯发送的高可用性与高吞吐量,但是有利有弊,这种 topic 共用文件的规划会使得 RocketMQ 不支撑删除指定 topic 功用,这也很好了解,关于某个 topic 的信息,在磁盘上的体现是一段非连续的区域,而不像 Kafka,一个 topic 就是一段连续的区域。如下图所示。
- RocketMQ 存储结构
下面我们来关键介绍 RocketMQ 的存储结构,通过对存储结构的了解,你将会更好地对读写功用有一个更深的知道。
不同 topic 共用一个文件的方式带来了高效的写功用,但是单看某一 topic 的信息,相关于磁盘上的体现为非连续的若干片段,这样使得定位指定 topic 下 msg 的信息,变成了一个棘手的问题。
RocketMQ 在出产进程中会把全部的 topic 信息次第写入 commitlog 文件中,消费进程中,运用 ConsumeQueue、IndexFile 索引文件完成数据的高功率读取。下面我们关键介绍这三类文件。
Commitlog: 从物理结构上来看,全部的音讯都存储在CommitLog里面,单个CommitLog文件大小默许1G,文件名长度为20位,左边补零,剩下为开端偏移量。
比如 00000000000000000000 代表了第一个文件,开端偏移量为0文件大小为 1G=1073741824;当第一个文件写满了,第二个文件为 00000000001073741824,开端偏移量为 1073741824,以此类推。音讯主要是次第写入日志文件,当文件满了,写入下一个文件。CommitLog 次第写,可以大大前进写入功率。
ConsumeQueue : (索引文件1)ConsumeQueue文件可以看成是根据 topic 的 commitlog 索引文件。Consumer 即可根据 ConsumeQueue 来查找待消费的音讯。
因为 ConsumeQueue 里只存偏移量信息,大部分的 ConsumeQueue 可以被全部读入内存,速度极快。在定位 msg 信息时直接读取偏移量,在 commitlog 文件中运用二分查找到对应的全量信息即可。
IndexFile: (索引文件2)IndexFile 是另一种可选索引文件,供给了一种可以通过 key 或时刻区间来查询音讯的办法。IndexFile 索引文件其底层完成为 hash 索引,Java 的 HashMap,可以快速通过 key 找到对应的 value。
讲到这儿,我们再想想 Kafka 是怎样做的,对的,Kafka 并没有类似的烦恼,因为全部信息都是连续的!以下是文件在目录下的存储示意图。
3.3 pulsar
- 架构图(分层+分片)
pulsar 比较于 Kafka 与 RocketMQ 最大的特色则是运用了分层和分片的架构,回想一下 Kafka 与 RocketMQ,一个服务节点就是核算节点也是服务节点,节点有情况使得途径化、容器化困难、数据搬家、数据扩缩容等运维作业都变得复杂且困难。
分层: Pulsar 分离出了 Broker(服务层)和 Bookie(存储层)架构,Broker 为无情况服务,用于发布和消费音讯,而 BookKeeper 专心于存储。
分片: 这种将存储从音讯服务中抽离出来,运用更细粒度的分片(Segment)替代粗粒度的分区(Partition),为 Pulsar 供给了更高的可用性,更灵活的扩展才干。
- 服务层规划
Broker 集群在 Pulsar 中构成无情况服务层。服务层是“无情况的”,全部的数据信息都存储在了 BookKeeper 上,全部的元信息都存储在了 zookeeper 上,这样使得一个 broker 节点没有任何的担负,这儿的担负有几层含义:
容器化没担负,broker 节点不用考虑任何数据情况带来的费事。 扩容、缩容没担负,当请求量级突增或许下降的一起,可以随时添加节点或许削减节点以动态的调整资源,使得整体在一种“适合”的情况。 缺点转移没担负,当一个节点宕机、服务不可用时,可以通过快速地转移所负责的 topic 信息到其他基节点上,可以很好做到缺点对外无感知。 |
---|
- 存储层规划
pulsar 运用了类似于 raft 的存储计划,数据会并发地写入多个存储节点上,下图为四存储节点、三副本架构。
broker2 节点当时需求写入 segment1 到 segment4 数据,流程为:segment1 并发写入 b1、b2、b3 数据节点、segment2 并发写入 b2、b3、b4数据节点、segment3并发写入 b3、b4、b1 数据节点、segment4 并发写入 b1、b2、b4 数据节点。这种写入办法称为条带化的写入办法、这种办法潜在地决定了数据的散布办法、通过路由算法,可以很快地找到对应数据的方位信息,在数据搬家与恢复中起到重要的效果。
- 扩容
当存储节点资源缺乏的时分,常规的运维操作就是动态扩容,比较 Kafka 与 RocketMQ、pulsar 不用考虑原数据的“人为”搬移作业,而是动态新增一个或许多个节点,broker 在写入数据时通过路有算法优先写入资源足够的节点,使得整体的资源运用力抵达一个平衡的情况,如图所示。
以下是一张 Kafka 分区和 pulsar 分片的一张对比图,左图是 Kafka 的数据存储特色,因为数据和分区的强绑定,导致了第三艘小船没有任何的数据,而比较 pulsar,数据欠好任何存储节点绑定,而是实时的动态写入,从数据散布和资源运用来说,要做得更好。
- 容灾
当 bookie4 存储节点宕机不可用时,怎样恢复节点数据?这儿只需求添加新的存储节点,并且拷贝 bookie2 与 bookie3 上的数据即可,这个进程对外是无感知的,完成了平滑切换,如图所示。
04、总结
纵观音讯队伍的展开史,技术的改造无疑处理了许多问题,每种规划的背后也都有着一种天然的平衡, 无论好坏,针对不同的场景,挑选不同的产品,才是王道。假设这篇文章对你有帮忙,欢迎转发收藏!
-End-
原创作者|吕昊俣
音讯队伍的运用场景是怎样的?欢迎在腾讯云开发者大众号谈论区同享。我们将选取1则最有含义的同享,送出腾讯云开发者-文化衫1件(见下图)。7月19日正午12点开奖。