分佈式消息隊列RocketMQ與Kafka的架構差別

咱們知道,在早期的RocketMQ版本中,是有依賴ZK的。而如今的版本中,是去掉了對ZK的依賴,轉而使用本身開發的NameSrv。架構

而且這個NameSrv是無狀態的,你能夠隨意的部署多臺,其代碼也很是簡單,很是輕量。ui

那不由要問了:ZooKeeper是業界用來管理集羣的一個很是經常使用的中間件,好比Kafka就是依賴的ZK。那爲何RocketMQ要本身造輪子,本身作集羣的管理呢?純粹就是再作一個Zookeeper嗎?spa

本篇試圖經過一個架構上的巨大差別,來闡述爲何RocketMQ能夠去掉ZK。.net

 

Kafka的架構拓撲圖中間件

咱們知道,在Kafka中,是1個topic有多個partition,每一個partition有1個master + 多個slave。對應以下圖所示:blog


注意:這裏只有3臺機器(b0,b1,b2),每臺機器既是Master,也是Slave。具體來講,好比機器b0,對於partition0來講,它多是Master;對應partition1來講,它可能又是Slave。隊列

RocketMQ的架構拓撲圖
不一樣於Kafka裏面,一臺機器同時是Master和Slave。在RocketMQ裏面,1臺機器只能要麼是Master,要麼是Slave。這個在初始的機器配置裏面,就定死了。其架構拓撲圖以下:路由

 

在這裏,RocketMQ裏面queue這個概念,就對應Kafka裏面partition。開發

有3個Master, 6個Slave,那對應到物理上面,就是3+6,得9臺機器!!!而不是上面像Kafka同樣,3臺機器。部署

Master/Slave/Broker概念上的差別
經過上面2張圖,咱們已經能夠直觀看出2者的巨大差別。反映到概念上,雖然2者都有Master/Slave/Broker這3個概念,但其含義是不同的。

Master/Slave概念差別
Kafka: Master/Slave是個邏輯概念,1臺機器,同時具備Master角色和Slave角色。
RocketMQ: Master/Slave是個物理概念,1臺機器,只能是Master或者Slave。在集羣初始配置的時候,指定死的。其中Master的broker id = 0,Slave的broker id > 0。

Broker概念差別
Kafka: Broker是個物理概念,1個broker就對應1臺機器。
RocketMQ:Broker是個邏輯概念,1個broker = 1個master + 多個slave。因此纔有master broker, slave broker這樣的概念。

那這裏,master和slave是如何配對的呢? 答案是經過broker name。具備同1個broker name的master和slave進行配對。

具體到配置裏面,以下:

//機器1的配置
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH

//機器2的配置
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH

//機器3的配置
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=2
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH

這裏機器1和機器2,機器3具備相同的brokerName(broker-a),一個brokerId = 0,另2個brokerId > 0。因此機器1是Master,機器2, 3是Slave。

因此這裏能夠看出:RokcetMQ和Kafka關於這2對概念的定義,恰好是反過來的!Kafka是先有Broker,而後產生出Master/Slave;RokcetMQ是先定義Master/Slave,而後組合出Broker。

答案:爲何能夠去ZK?
從上面對比能夠看出,Kafka和RocketMQ在Master/Slave/Broker這個3個概念上的差別。

這個差別,也就影響到topic, partition這種邏輯概念和Master/Slave/Broker這些物理概念上的映射關係。具體來說就是:

在Kafka裏面,Maser/Slave是選舉出來的!!!RocketMQ不須要選舉!!!

在Kafka裏面,Maser/Slave是選舉出來的!!!RocketMQ不須要選舉!!!

在Kafka裏面,Maser/Slave是選舉出來的!!!RocketMQ不須要選舉!!!

重要的話說三篇。具體來講,在Kafka裏面,Master/Slave的選舉,有2步:第1步,先經過ZK在全部機器中,選舉出一個KafkaController;第2步,再由這個Controller,決定每一個partition的Master是誰,Slave是誰。

這裏的Master/Slave是動態的,也就是說:當Master掛了以後,會有1個Slave切換成Master。

而在RocketMQ中,不須要選舉,Master/Slave的角色也是固定的。當一個Master掛了以後,你能夠寫到其餘Master上,但不會說一個Slave切換成Master。

這種簡化,使得RocketMQ能夠不依賴ZK就很好的管理Topic/queue和物理機器的映射關係了,也實現了高可用。

這裏,也涉及到了我在上1篇裏,所說的「消息順序」的問題:在Kafka裏面,一個partition必須與1個Master有嚴格映射關係,這個Master掛了,就要從其餘Slave裏面選舉出一個Master;而在RocketMQ裏面,這個限制放開了,一個queue對應的Master掛了,它會切到其餘Master,而不是非要選舉出來一個。

說到這,答案基本就知道了:RocketMQ不須要像Kafka那樣有很重的選舉邏輯,它把這個問題簡化了。剩下的就是topic/queue的路由信息,那用個簡單的NameServer就搞定了,很輕量,還無狀態,可靠性也能獲得很好保證。

Topic的建立過程
下面從使用的角度,看看Kafka和RocketMQ在建立topic的時候,分別都須要指定什麼參數?

從這些參數也能夠看出,2者的topic, partition這種邏輯概念和物理機器之間的映射關係,有很大不一樣。

RocketMQ建立topic的命令
下面代碼來自UpdateTopicSubCommand這個類,也就是RocketMq建立topic時,調用的類。這裏有幾個關鍵參數,其餘參數我省略了:
b:
c: //b和c2選1,b是指定topic所在的機器,c是指定topic所在的cluster

topic: //這個是基本參數,沒什麼好講的

readQueueNums/writeQueueNums: //隊列個數。缺省2者相等,是8。關於這個readQueueNums/writeQueueNums,是RocketMQ特有的概念,後面再來詳細分析。此處就認爲他們2者相等,是同1個。

Option opt = new Option("b", "brokerAddr", true, "create topic to which broker");
opt.setRequired(false);
options.addOption(opt);

opt = new Option("c", "clusterName", true, "create topic to which cluster");
opt.setRequired(false);
options.addOption(opt);

opt = new Option("t", "topic", true, "topic name");
opt.setRequired(true);
options.addOption(opt);

opt = new Option("r", "readQueueNums", true, "set read queue nums");
opt.setRequired(false);
options.addOption(opt);

opt = new Option("w", "writeQueueNums", true, "set write queue nums");
opt.setRequired(false);
options.addOption(opt);

。。。

Kafka建立topic的命令
跟RocketMQ相比,有2個一樣的參數:1個是topic,一個是隊列數目,也就是這裏的–partitions。

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic

二者在建立topic時一個顯著的不一樣
Kafka有一個參數replication-factor,也就是指定給1個Master配幾個Slave?

RocketMQ有一個參數c,也就是clusterName,來指定這個cluster裏面,全部的Master和Slave的配對(多個master, 多個slave) 對應同1個topic!!!

缺省狀況下,全部的Master和Slave屬於同1個集羣,也就是上面的3臺機器配置中的第1個參數:brokerClusterName=DefaultCluster。

結合上面的架構拓撲圖,咱們就能夠看出:
對於kafka來講,你指定topic,它的partition個數,它的master/slave配比,而後系統自動從全部機器中,爲每一個topic_partition分配1個master + 多個slave;

對於RokcetMQ來講,你指定topic,它的queue個數,它對應的cluster。而後系統自動創建這個cluster(多個master + 多個slave) 和你的topic之間的映射關係。

原文:https://blog.csdn.net/chunlongyu/article/details/54018010 

相關文章
相關標籤/搜索