编者荐语:
文章作者为中国移动云能力核心,文章转载已受权。本文将具体解析基于 Apache Pulsar 的云原生音讯队列 AMQP 背景与整体设计等深度内容。
以下文章来源于苏研大云人,作者云原生中间件团队
情谊提醒:全文5000多文字,预计浏览工夫3分钟
一、自研音讯队列中间件AMQP的背景
随着公司私有云业务继续倒退和用户数量的一直增长,数据量和申请量也在急剧增长,音讯队列作为必不可少的通信组件,面临的压力也在日益增长。在对音讯队列的组件保护中咱们发现:OpenStack应用的音讯队列RabbitMQ存在一些问题,比方音讯易失落,集群稳定性差,问题排查艰难等。诸多难以解决的问题使咱们萌发了寻求代替开源RabbitMQ音讯队列的想法;另一方面,支流云服务厂商,如阿里云、华为云、天翼云等均已提供AMQP协定反对的音讯队列产品,而咱们短少自研对标产品。基于以上两点,团队开始自研一款高性能、高牢靠、高稳固,反对AMQP协定的音讯队列产品。
咱们的需要
综合云上产品和挪动云组件的需要,整顿了音讯队列AMQP的几大外围需要如下:
- 具备高吞吐量,低提早,高牢靠的能力;
- 能依据需要进行无限度的扩容,缩容;
- 对于上云产品来说,须要具备多租户隔离的能力;
- 具备海量音讯沉积能力,并且音讯的沉积不会影响性能和稳定性;
- 反对AMQP协定,兼容AMQP协定的客户端(比方,开源RabbitMQ SDK);
- 具备运维部署能力,数据迁徙的便利性,具备高效的集群部署、迁徙效率。
开源产品调研
在产品设计之初,研发团队次要调研了两款实现了AMQP协定的开源产品:RabbitMQ和Qpid。因为Qpid在性能方面体现不佳被排除在外,RabbitMQ性能高、应用范围广,然而不合乎咱们的需要应用场景,有如下几个起因:
- 长久化音讯性能较差。为了保障音讯不失落且音讯可回溯,须要将音讯长久化存储,通过测试RabbitMQ的长久化音讯性能较差,不满足咱们的需要,详见第四章节的性能测试比照。
- 为了保障音讯不失落,能够应用RabbitMQ的镜像队列,镜像队列的机制就是音讯多正本保留在多节点的内存中,通过测试发现,在开启镜像队列的场景下,会呈现两方面的问题:首先是集群稳定性较差,其次是音讯沉积会导致内存溢出。
- 问题排查的困难性,RabbitMQ的编程语言是Erlang,这种编程语言较为小众。RabbitMQ的源码艰涩难懂,导致呈现问题时,排查艰难,且RabbitMQ没有实时音讯追踪的能力,须要开启音讯追踪的插件,无奈及时回溯呈现问题的音讯。
基于以上起因,咱们开始音讯队列AMQP的自研。
二、音讯队列AMQP整体设计
计算存储拆散的架构
思考到高稳定性、高可靠性和高吞吐量等诸多设计指标,研发团队最终决定采纳合乎云原生设计理念的计算存储拆散架构。
计算存储耦合和计算存储拆散有如下几个方面的比照:
当存储和计算耦合在一个集群中时,存在如下的一些问题:
- 在不同的利用或者倒退期间,须要不同的存储空间和计算能力配比,使得机器的选型会比较复杂;
- 当存储空间或计算资源有余时,只能同时对两者进行扩容,导致扩容的经济效率比拟低(另一种扩容的资源被节约了);
- 在云计算场景下,不能实现真正的弹性计算,因为计算集群中也有数据,敞开闲置的计算集群会失落数据。
针对计算存储耦合带来的一些问题,研发团队也调研了具备计算存储拆散能力的开源音讯队列Apache Pulsar。
在Pulsar的架构中,计算和数据存储是独自的两个组件:
计算层也就是Broker,Pulsar的Broker不间接存储音讯实体数据,次要负责解决Consumer和Producer相干的连贯申请解决等,如果业务上Consumer和Producer特地的多,能够独自扩大这一层。
数据存储也就是Bookie,Pulsar应用了Apache BookKeeper作为存储反对,BookKeeper是一个提供日志条目流存储长久化的服务框架,计算层应用时不用过多的关怀存储细节。
联合音讯队列AMQP的利用场景以及剖析面向的客户群体,咱们抉择Pulsar这种计算存储拆散的音讯队列作为原型进行音讯队列AMQP的定制化开发。在调研Pulsar以及与Puslar社区深刻沟通之后发现Pulsar现有的Protocol Handler机制十分合乎咱们这种定制化开发的需要,Protocol Handler协定解决插件能够利用Pulsar 现有的一些组件(例如 服务发现组件-Topic LookUp、分布式日志库-ManagedLedger、生产进度治理组件-Cursor 等)来帮忙咱们实现一些逻辑解决。
因而Pulsar的Protocol Handler就成为了咱们音讯队列AMQP定制化开发的根底。更多Protocol Handler的介绍可参考Pulsar PIP-41。
(https://github.com/apache/pul...)
音讯队列AMQP整体架构如上图所示,开发的重点就在于AMQP Protocol Handler的通信层协定的解析解决、AMQP 0-9-1协定模型与Pulsar模型之间的映射、多租户的反对以及最外围的发送生产流程的解决。
外围性能点设计
- 音讯的存储
音讯队列AMQP的存储设计借鉴了RabbitMQ,最终实现利用Pulsar的PersistentTopic来实现具体的实体数据以及索引数据的存储。
1、RabbitMQ的音讯存储模型
RabbitMQ的音讯长久化理论包含两局部:队列索引(rabbit_queue_index)和音讯存储(rabbit_msg_store)。
rabbit_queue_index负责保护队列中落盘音讯的信息,包含音讯的存储位点、是否曾经提交给消费者、是否已被消费者ACK等,每个队列都有一个与之对应的rabbit_queue_index。
rabbit_msg_store以键值对的模式存储音讯,每个节点有且只有一个,该节点上的所有队列共享该文件。从技术层面讲rabbit_msg_store又能够分为msg_store_persistent和msg_store_transient,其中msg_store_persistent负责长久化音讯的存储,不会失落;而msg_store_transient负责非长久化音讯的存储,重启后音讯会失落。
2、BookKeeper提供存储反对
Pulsar broker中的ManagedLedger实现了对BookKeeper存储层的封装,利用ManagedLedger能够实现音讯的长久化、读取以及生产进度治理。
3、如何利用Pulsar现有的模型实现exchange以及queue的对应
AMQP 0-9-1引入了一些根底概念,例如 Exchagne, Queue 和 Router。这些与 Pulsar 的模型有着较大的区别。因而,咱们须要采纳一种建模映射形式,将现有Pulsar中对于Topic的公布/订阅模型与AMQP通信协议中的业务模型映射到一起。
AmqpExchange
AmqpExchange 蕴含一个原始音讯 Topic,用来保留 AMQP Producer 发送的音讯。AmqpExchange 的 Replicator 会将音讯解决到 AMQP 队列中。Replicator 是基于 Pulsar 的长久化游标,能够确保胜利将音讯发送到队列,而不会失落音讯。
AmqpMessageRouter
AmqpMessageRouter 用于保护音讯路由类型以及将音讯从 AmqpExchange 路由到 AmqpQueue 的路由规定。路由类型和路由规定这些元数据都长久化在 Pulsar 的ManagedLedger 中。所以就算 Broker 重启,咱们也能够复原 AmqpMessageRouter。
AmqpQueue
AmqpQueue 提供一个索引音讯 Topic,用来存储路由到这个队列的 IndexMessage。IndexMessage 由原始音讯的 ID 和存储音讯的 Exchange 的名称组成。当 AmqpQueue 向 Consumer 发送音讯时,AmqpQueue 会依据 IndexMessage 读取原始音讯数据,而后将其发送给 Consumer。
- 多租户的反对
作为一种企业级的音讯零碎,Pulsar 的多租户能力可满足下列需要:
- 保障不同租户之间的隔离
- 针对资源利用率强制施行配额
- 提供每租户和零碎级的安全性
- 确保低成本运维以及尽可能简略的治理
Pulsar多租户的个性,在topic的URL映射上充沛浮现,构造如下:
AMQP 0-9-1的协定定义中,VirtualHost是资源隔离的根本单位,和Pulsar的这种多层级的模型不能有完全一致的对应关系,在咱们的实现中,挪动云AMQP音讯队列引入了Instance的概念,对应到Pulsar中的Tenant,组件版本应用固定的Tenant,Pulsar中的Namespace则对应到AMQP中的VirtualHost。其中组件版本的对应图如下所示:
- 音讯流转过程
- 当 Producer 发送音讯到 AmqpExchange,AmqpExchange 将音讯长久化到 Pulsar Topic (咱们称之为存储原始音讯的 Topic)。
- AmqpExchange 的 Replicator 会将消息传递给 Router。
- Router 判断是否须要将音讯路由给 AmqpQueue。如果是,会将原始音讯的 ID 存入AmqpQueue 的 Topic 中 (咱们称之为存储索引音讯的 Topic)。
- AmqpQueue 将消息传递给 Consumer。
三、音讯队列AMQP和RabbitMQ比拟
云原生
云原生的"原生"即软件设计之初就思考到了在云端部署的可能,音讯队列AMQP采纳计算存储拆散的外围架构,可能充分利用分布式、弹性伸缩的云端资源。
传统架构下的音讯队列如RabbitMQ,将音讯存储在本地,Broker组件需承担音讯散发和存储的双重性能;这使得Broker并非无状态服务,不具备弹性伸缩的能力。
而自研音讯队列AMQP通过计算存储拆散的架构,将Broker的角色进一步拆分为用于音讯散发的Broker和用于音讯存储的Bookie,从而将Broker打造成无状态服务,以实现Broker的弹性伸缩。
音讯可靠性
音讯的不失落通常由两个方面保障:首先音讯须要长久化到磁盘中,其次长久化音讯须要保留多正本以晋升音讯队列的容错能力。相较于音讯队列RabbitMQ,自研AMQP在音讯可靠性的保障方面具备以下劣势:
RabbitMQ长久化音讯采纳异步刷盘机制,无奈保障断电、硬件故障等极其状况下数据的不失落;音讯队列AMQP原生反对音讯同步刷盘,能够保障除磁盘损坏的任何极其故障场景下,音讯的不失落。
RabbitMQ仅在开启镜像队列时才可能进行音讯的多正本同步;而音讯队列AMQP原生反对音讯的多正本保留,局部节点磁盘损坏状况下,数据也可能从正本中复原进去。
RabbitMQ在开启音讯长久化和镜像队列时,性能很差,无奈满足高性能的需要;而音讯队列AMQP通过文件的程序读取和音讯的缓存机制,仍能保障极高的性能。
容错
容错指集群中局部节点产生故障的时候,集群的可用性。
RabbitMQ的容错性不高,在产生网络分区的状况下,会导致数据失落和集群的不可用,尤其是在配置镜像队列的状况下。
而音讯队列AMQP各个组件都能够独立的容错。Broker是无状态服务,当产生谬误的时候,Queue就会转移到其余Broker,不会影响音讯收发。Bookie尽管有状态,然而并无主从之分,只有音讯的正本足够多,即便局部Bookie宕机或者不可用的状况下,服务仍然能够失常运行。
可维护性
相较于RabbitMQ,自研AMQP提供更加欠缺的运维监控零碎,对于零碎的各项指标,比方TPS、容量、连贯状态、消费者状态等各项指标均有具体的监控,同时提供欠缺的阐明文档以应答可能呈现的各类问题,便于故障排查。
RabbitMQ不具备实时音讯追踪能力,无奈及时回溯呈现问题的音讯;而AMQP具备音讯追踪的性能,保障所有音讯可追溯,为问题的排查提供了便当。
RabbitMQ采纳Erlang语言,较为小众且艰涩难懂,很难进行源码级别的问题排查;而AMQP为自研中间件,所有问题都能够通过代码剖析排查解决。
四、性能
在同样的环境下,对音讯队列AMQP和RabbitMQ的单机性能进行测试:
音讯体大小:1KB
exchange数量:1个
queue数量:1个
音讯是否长久化:是
通过创立1个Queue,1个Exchange,发送1KB的音讯,比照音讯队列AMQP和RabbitMQ的性能,失去上述的折线图,从上图能够看出,在等同测试条件下,音讯队列AMQP的性能体现远高于RabbitMQ。
五、总结
目前音讯队列AMQP曾经正式上线挪动云,欢送大家订购应用。
(https://ecloud.10086.cn/home/...)
另外音讯队列AMQP组件版本替换OpenStack中RabbitMQ也曾经实现测试环境的验证工作,后续会在挪动云生产环境中作为OpenStack组件的通信组件应用。
参考资料
1、Apache Pulsar 官网:https://pulsar.apache.org/doc...
2、《RabbitMQ 实战指南》
END
作者简介
张浩
中国移动云能力核心中间件开发工程师,音讯队列AMQP研发负责人,在消息中间件以及分布式缓存畛域有丰盛的教训。
王少杰
中国移动云能力核心软件开发工程师,次要负责挪动云音讯队列产品研发、性能调优和保护工作,在RocketMQ,Pulsar,RabbitMQ等方面有丰盛的实际和优化教训。
欢送投稿
Apache Pulsar 社区欢送大家踊跃投稿,心愿这里成为大家获取 Pulsar 教训与常识分享的平台,并帮忙更多的社区小伙伴深刻理解 Pulsar。扫码增加 Bot 好友即可联系投稿
点击链接拜访原文。