导语 | 本文次要介绍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。
应用场景
为金融互联网畛域而生,对于可靠性要求很高的场景。
作者简介
陈冬,腾讯后盾开发工程师。