乐趣区

关于消息队列:带你玩转消息队列和相关选型

导语 | 本文次要介绍 Kafka、RabbitMQ、Pulsar、RocketMQ 相干的基本原理和选型比照,心愿对此方向感兴趣的读者提供肯定教训和帮忙。

一、音讯队列

(一)音讯队列应用场景

音讯队列中间件是分布式系统中重要的组件,次要解决利用耦合,异步音讯,削峰填谷等问题。实现高性能、高可用、可伸缩和最终一致性架构。

解耦:多个服务监听、解决同一条音讯,防止屡次 rpc 调用。

异步音讯:音讯发布者不必期待音讯解决的的后果。

削峰填谷:较大流量、写入场景,为上游 I / O 服务抗流量。当然大流量下就须要应用其余计划了。

音讯驱动框架:在事件总线中,服务通过监听事件音讯驱动服务实现相应动作。

(二)音讯队列模式

点对点模式,不可反复生产

多个生产者能够向同一个音讯队列发送音讯,一个音讯在被一个音讯者生产胜利后,这条音讯会被移除,其余消费者无奈解决该音讯。如果消费者解决一个音讯失败了,那么这条音讯会从新被生产。

公布 / 订阅模式

公布订阅模式须要进行注册、订阅,依据注册生产对应的音讯。多个生产者能够将音讯写到同一个 Topic 中,多种音讯能够被同一个消费者生产。一个生产者生产的音讯,同样也能够被多个消费者生产,只有他们进行过音讯订阅。

二、选型参考

音讯程序:发送到队列的音讯,生产时是否能够保障生产的程序。

伸缩:当音讯队列性能有问题,比方生产太慢,是否能够疾速反对库容;当生产队列过多,节约系统资源,是否能够反对缩容。

音讯留存:音讯生产胜利后,是否还会持续保留在音讯队列。

容错性:当一条音讯生产失败后,是否有一些机制,保障这条音讯是一种能胜利,比方异步第三方退款音讯,须要保障这条音讯生产掉,能力确定给用户退款胜利,所以必须保障这条音讯生产胜利的准确性。

音讯可靠性:是否会存在丢音讯的状况,比方有 A / B 两个音讯,最初只有 B 音讯能生产,A 音讯失落。

音讯时序:次要包含“音讯存活工夫”和“提早音讯”。

吞吐量:反对的最高并发数。

音讯路由:依据路由规定,只订阅匹配路由规定的音讯,比方有 A / B 两者规定的音讯,消费者能够只订阅 A 音讯,B 音讯不会生产。

(一)Kafka

Kafka 是由 Apache 软件基金会开发的一个开源流解决平台,由 Scala 和 Java 编写。该项目标指标是为解决实时数据提供一个对立、高吞吐、低提早的平台。其长久化层实质上是一个“依照分布式事务日志架构的大规模公布 / 订阅音讯队列”,这使它作为企业级基础设施来解决流式数据十分有价值。(维基百科)

根本术语

Producer:音讯生产者。个别状况下,一条音讯会被发送到特定的主题上。通常状况下,写入的音讯会通过轮询将音讯写入各分区。生产者也能够通过设定音讯 key 值将音讯写入指定分区。写入分区的数据越平均 Kafka 的性能能力更好施展。

Topic:Topic 是个形象的虚构概念,一个集群能够有多个 Topic,作为一类音讯的标识。一个生产者将音讯发送到 topic,消费者通过订阅 Topic 获取分区音讯。

Partition:Partition 是个物理概念,一个 Topic 对应一个或多个 Partition。新音讯会以追加的形式写入分区里,在同一个 Partition 里音讯是有序的。Kafka 通过分区,实现音讯的冗余和伸缩性,以及反对物理上的并发读、写,大大提高了吞吐量。

Replicas:一个 Partition 有多个 Replicas 正本。这些正本保留在 broker,每个 broker 存储着成千盈百个不同主题和分区的正本,存储的内容分为两种:master 正本,每个 Partition 都有一个 master 正本,所有内容的写入和生产都会通过 master 正本;follower 正本不解决任何客户端的申请,只同步 master 的内容进行复制。如果 master 产生了异样,很快会有一个 follower 成为新的 master。

Consumer:音讯读取者。消费者订阅主题,并依照肯定程序读取音讯。Kafka 保障每个分区只能被一个消费者应用。

Offset:偏移量是一种元数据,是一直递增的整数。在音讯写入时 Kafka 会把它增加到音讯里。在分区内偏移量是惟一的。生产过程中,会将最初读取的偏移量存储在 Kafka 中,消费者敞开偏移量不会失落,重启会持续从上次地位开始生产。

Broker:独立的 Kafka 服务器。一个 Topic 有 N 个 Partition,一个集群有 N 个 Broker,那么每个 Broker 都会存储一个这个 Topic 的 Partition。如果某 topic 有 N 个 partition,集群有 (N+M) 个 broker,那么其中有 N 个 broker 存储该 topic 的一个 partition,剩下的 M 个 broker 不存储该 topic 的 partition 数据。如果某 topic 有 N 个 partition,集群中 broker 数目少于 N 个,那么一个 broker 存储该 topic 的一个或多个 partition。在理论生产环境中,尽量避免这种状况的产生,这种状况容易导致 Kafka 集群数据不平衡。

零碎框架

第一个 topic 有两个生产,新音讯被写入到 partition 1 或者 partition 2,两个分区在 broker1、broker2 都有备份。有新音讯写入后,两个 follower 分区会从两个 master 分区同步变更。对应的 consumer 会从两个 master 分区依据当初 offset 获取音讯,并更新 offset。第二个 topic 只有一个生产者,同样对应两个 partition,扩散在 Kafka 集群的两个 broker 上。有新音讯写入,两个 follower 分区会同步 master 变更。两个 Consumer 别离从不同的 master 分区获取音讯。

长处

高吞吐量、低提早:kafka 每秒能够解决几十万条音讯,它的提早最低只有几毫秒;

可扩展性:kafka 集群反对热扩大;

持久性、可靠性:音讯被长久化到本地磁盘,并且反对数据备份避免数据失落;

容错性:容许集群中节点故障,一个数据多个正本,多数机器宕机,不会失落数据;

高并发:反对数千个客户端同时读写。

毛病

分区有序:仅在同一分区内保障有序,无奈实现全局有序;

无延时音讯:生产程序是依照写入时的程序,不反对延时音讯;

反复生产:生产零碎宕机、重启导致 offset 未提交;

Rebalance:Rebalance 的过程中 consumer group 下的所有消费者实例都会进行工作,期待 Rebalance 过程实现。

应用场景

日志收集:大量的日志音讯先写入 kafka,数据服务通过生产 kafka 音讯将数据落地。

音讯零碎:解耦生产者和消费者、缓存音讯等。

用户流动跟踪:kafka 常常被用来记录 web 用户或者 app 用户的各种流动,如浏览网页、搜寻、点击等流动,这些流动信息被各个服务器公布到 kafka 的 topic 中,而后消费者通过订阅这些 topic 来做实时的监控剖析,亦可保留到数据库。

经营指标:记录经营、监控数据,包含收集各种分布式应用的数据,生产各种操作的集中反馈,比方报警和报告。流式解决:比方 spark streaming。

(二)RabbitMQ

RabbitMQ 是实现了高级音讯队列协定(AMQP)的开源音讯代理软件(亦称面向音讯的中间件(英语:Message-oriented middleware))。RabbitMQ 服务器是用 Erlang 语言编写的,而群集和故障转移是构建在凋谢电信平台框架上的。所有次要的编程语言均有与代理接口通信的客户端函式库。(维基百科)

根本术语

Broker:接管客户端链接实体,实现 AMQP 音讯队列和路由性能。

Virtual Host:是一个虚构概念,权限管制的最小单位。一个 Virtual Host 里蕴含多个 Exchange 和 Queue。

Exchange:接管音讯生产者的音讯并将音讯转发到队列。发送音讯时依据不同 ExchangeType 的决定路由规定,ExchangeType 罕用的有:direct、fanout 和 topic 三种。

Message Queue:音讯队列,存储为被生产的音讯。

Message:由 Header 和 Body 组成,Header 是生产者增加的各种属性,蕴含 Message 是否长久化、哪个 MessageQueue 接管、优先级。Body 是具体的音讯内容。

Binding:Binding 连贯起了 Exchange 和 Message Queue。在服务器运行时,会生成一张路由表,这张路由表上记录着 MessageQueue 的条件和 BindingKey 值。当 Exchange 收到音讯后,会解析音讯中的 Header 失去 BindingKey,并依据路由表和 ExchangeType 将音讯发送到对应的 MessageQueue。最终的匹配模式是由 ExchangeType 决定。

Connection:在 Broker 和客户端之间的 TCP 连贯。

Channel:信道。Broker 和客户端只有 tcp 连贯是不能发送音讯的,必须创立信道。AMQP 协定规定只有通过 Channel 能力执行 AMQP 命令。一个 Connection 能够蕴含多个 Channel。之所以须要建设 Channel,是因为每个 TCP 连贯都是很贵重的。如果每个客户端、每个线程都须要和 Broker 交互,都须要保护一个 TCP 连贯的话是机器消耗资源的,个别倡议共享 Connection。RabbitMQ 不倡议客户端线程之前共享 Channel,至多保障同一 Channel 发小音讯是穿行的。

Command:AMQP 命令,客户端通过 Command 来实现和 AMQP 服务器的交互。

零碎框架

一条 Message 通过信道达到对应的 Exchange,Exchange 收到音讯后解析出音讯 Header 内容,获取音讯 BindingKey 并依据 Binding 和 ExchangeType 将音讯转发到对应的 MessageQueue,最初通过 Connection 将音讯传送的客户端。

ExchangeType

Direct:准确匹配

只有 RoutingKey 和 BindingKey 齐全匹配的时候,音讯队列才能够获取音讯

Broker 默认提供一个 Exchange,类型是 Direct 名字是空字符串,绑定到所有的 Queue(这里通过 Queue 名字来辨别)

Fanout:订阅、播送

这个模式会将音讯转发到所有的路由的 Queue 中

Topic:通配符模式

RoutingKey 为一个句点号“.”分隔的字符串(将被句点号“.”分隔开的每一段独立的字符串称为一个单词),如“quick.orange.rabbit”。BindingKey 与 RoutingKey 一样。

Bindingkey 中的两个特殊字符“#”和“”用于含糊匹配,“#”用于匹配多个单次,“”用来匹配单个单词(蕴含零个)

长处

基于 AMQP 协定:除了 Qpid,RabbitMQ 是惟一一个实现了 AMQP 规范的音讯服务器。

强壮、稳固、易用。社区沉闷,文档欠缺。

反对定时音讯。可插入的身份验证,受权,反对 TLS 和 LDAP。

反对依据音讯标识查问音讯,也反对依据音讯内容查问音讯。

毛病

erlang 开发源码难懂,不利于做二次开发和保护。

接口和协定简单,学习和保护老本较高。

总结

erlang 有并发劣势,性能较好。尽管源码简单,然而社区活跃度高,能够解决开发中遇到的问题。业务流量不大的话能够抉择性能比拟齐备的 RabbitMQ。

(三)Pulsar

Apache Pulsar 是 Apache 软件基金会顶级我的项目,是下一代云原生分布式音讯流平台,集音讯、存储、轻量化函数式计算为一体,采纳计算与存储拆散架构设计,反对多租户、长久化存储、多机房跨区域数据复制,具备强一致性、高吞吐、低延时及高可扩展性等流数据存储个性,被看作是云原生时代实时音讯流传输、存储和计算最佳解决方案。Pulsar 是一个 pub-sub (公布 - 订阅)模型的音讯队列零碎。(百科)

根本术语

Property:代表租户,每个 property 都能够代表一个团队、一个性能、一个产品线。一个 property 可蕴含多个 namesapce,多租户是一种资源隔离伎俩,能够进步资源利用率。

Namespace:Pulsar 的根本治理单元,在 namaspace 级别可设置权限、音讯 TTL、Retention 策略等。一个 namaspace 里的所有 topic 都继承雷同的设置。命名空间分为两种:本地命名空间,只在集群内可见、全局命名空间对多个集群可见集群命名空间。

Producer:数据生产方,负责创立音讯并将音讯投递到 Pulsar 中。

Consumer:数据生产方,连贯到 Pulsar 接管音讯并进行相应的解决。

Broker:无状态 Proxy 服务,负责接管音讯、传递音讯、集群负载平衡等操作,它对 client 屏蔽了服务端读写流程的复杂性,是保证数据一致性与数据负载平衡的重要角色。Broker 不会长久化保留元数据。能够扩容但不能缩容。

BookKeeper:有状态,负责长久化存储音讯。当集群扩容时,Pulsar 会在新增 BookKeeper 和 Segment(即 Bookeeper 的 Ledger),不须要像 kafka 一样在扩容时进行 Rebalance。扩容后果是 Fragments 跨多个 Bookies 以带状散布,同一个 Ledger 的 Fragments 散布在多个 Bookie 上,导致读取和写入会在多个 Bookies 之间跳跃。

ZooKeeper:存储 Pulsar、BookKeeper 的元数据,集群配置等信息,负责集群间的协调、服务发现等。

Topic:用作从 producer 到 consumer 传输音讯。Pulsar 在 Topic 级别领有一个 leader Broker,称之为领有 Topic 的所有权,针对该 Topic 所有的 R/W 都通过该 Broker 实现。Topic 的 Ledger 和 Fragment 之间映射关系等元数据存储在 Zookeeper 中,Pulsar Broker 须要实时跟踪这些关系进行读写流程。

Ledger:即 Segment,Pulsar 底层数据以 Ledger 的模式存储在 BookKeeper 上。是 Pulsar 删除的最小单位。

Fragment:每个 Ledger 由若干 Fragment 组成。

零碎框架

下面框架图别离演示了扩容、故障转移两种状况。扩容:因业务量增大扩容新增 Bookie N,后续写入的数据 segment x、segment y 写入新增 Bookie 中,为放弃平衡扩容后果如上图绿色模块所示。故障转移:Bookie 2 的 segment 4 产生故障,Pulasr 的 Topic 会立马从新抉择 Bookie 1 作为解决读写的服务。Broker 是无状态的服务,只服务数据计算不存储,所以 Pulsar 能够认为是一种基于 Proxy 的分布式系统。

长处

灵便扩容。

无缝故障复原。

反对延时音讯。

内置的复制性能,用于跨地区复制,如灾备。

反对两种生产模型:流(独享模式)、队列(共享模式)。

(四)RocketMQ

RocketMQ 是一个分布式音讯和流数据平台,具备低提早、高性能、高可靠性、万亿级容量和灵便的可扩展性。RocketMQ 是 2012 年阿里巴巴开源的第三代分布式消息中间件。(维基百科)

根本术语

Topic:一个 Topic 能够有 0 个、1 个、多个生产者向其发送音讯,一个生产者也能够同时向不同的 Topic 发送音讯。一个 Topic 也能够被 0 个、1 个、多个消费者订阅。

Tag:音讯二级类型,能够为用户提供额定的灵便度,一条音讯能够没有 tag。

Producer:音讯生产者。

Broker:存储音讯,以 Topic 为纬度轻量级的队列;转发音讯,单个 Broker 节点与所有的 NameServer 节点放弃长连贯及心跳,会定时将 Topic 信息注册到 NameServer。

Consumer:音讯消费者,负责接管并生产音讯。

MessageQueue:音讯的物理治理单位,一个 Topic 能够有多个 Queue,Queue 的引入实现了程度扩大的能力。

NameServer:负责对原数据的治理,包含 Topic 和路由信息,每个 NameServer 之间是没有通信的。

Group:一个组能够订阅多个 Topic,ProducerGroup、ConsumerGroup 别离是一类生产者和一类消费者。

Offset:通过 Offset 拜访存储单元,RocketMQ 中所有音讯都是长久化的,且存储单元定长。Offset 为 Java Long 类型,实践上 100 年内不会溢出,所以认为 Message Queue 是有限长的数据,Offset 是下标。

Consumer:反对 PUSH 和 PULL 两种生产模式,反对集群生产和播送生产。

零碎框架

长处

反对公布 / 订阅(Pub/Sub)和点对点(P2P)音讯模型。

程序队列:在一个队列中牢靠的先进先出(FIFO)和严格的程序传递。

反对拉(pull)和推(push)两种音讯模式。

繁多队列百万音讯的沉积能力。

反对多种音讯协定,如 JMS、MQTT 等。

分布式横向扩大架构。

满足至多一次消息传递语义。

提供丰盛的 Dashboard,蕴含配置、指标和监控等。

反对的客户端,目前是 java、c++ 及 golang。

毛病

社区活跃度个别。

延时音讯:开源版不反对任意工夫精度,仅反对特定的 level。

应用场景

为金融互联网畛域而生,对于可靠性要求很高的场景。

作者简介

陈冬,腾讯后盾开发工程师。

退出移动版