kafka和rocketmq

kafka:日志傳輸
rocketmq:訂單,交易,充值,流計(jì)算,消息推送,日志流式處理,binglog分發(fā)

0. kafka 與 zookeeper原理

kafka:

  1. producer端使用zookeeper用來"發(fā)現(xiàn)"broker列表,以及和topic下每個partition master建立socket連接并發(fā)送消息
  2. broker端使用zookeeper用來注冊broker信息,已及監(jiān)測partition master存活性
  3. consumer端使用zookeeper用來注冊consumer信息,其中包括consumer消費(fèi)的partition列表等,同時也用來發(fā)現(xiàn)broker列表,并和partition master建立socket連接,并獲取消息

1. namesvr與zookeeper

kafka的架構(gòu):

  1. topic --(選擇partition個數(shù))--> partition-n -- (根據(jù)設(shè)置副本zookeeper選舉出1-master/n-slave)--> replication-n --> 系統(tǒng)自動從所有機(jī)器中為每個topic_partition分配1個master + 多個slave
  2. 由于master/slave需要選舉,所以使用zookeeper
  3. 一個節(jié)點(diǎn)既可以是master也可以是slave
  4. partition master掛了,slave選舉成為新的master(通過controller使用zk選舉產(chǎn)生)
    1. 通過zk的臨時節(jié)點(diǎn)競爭選出broker cluster中的controller
    2. 通過controller使用groupId+topic在__consumer_offset的partition leader作為group coordinator
    3. 通過coordinator選出所有consumer中的一個作為leader consumer
    4. 由leader consumer進(jìn)行分配上報(bào)給coordinator, coordinator再下發(fā)給所有consumer**)
  5. broker物理概念,對應(yīng)一臺物理機(jī),partition邏輯概念
  6. 先有broker,然后產(chǎn)生出master/slave
  7. producer端發(fā)送的message必須指定是發(fā)送到哪個topic,但是不需要指定topic下的哪個partition,因?yàn)閗afka會把收到的message進(jìn)行load balance,均勻的分布在這個topic下的不同的partition上( hash(message) % [broker數(shù)量] )
  8. producer先把message發(fā)送到partition master,再由master轉(zhuǎn)發(fā)給其他partition slave,master反饋ack給producer需要保證有n個replica已經(jīng)收到該消息
    kafka架構(gòu).png

rocketmq的架構(gòu):

  1. topic --(選擇queue個數(shù))--> queue-n --(機(jī)器啟動時指定clusterName對應(yīng)的brokerId)-->clusterName --> 系統(tǒng)自動分配cluster(多個master + 多個slave) 和你的topic之間的映射關(guān)系
  2. 由于部署時已經(jīng)定義好,無需選舉,只需要namesvr進(jìn)行狀態(tài)監(jiān)控topic->queue關(guān)系即可
  3. 一個節(jié)點(diǎn)(同一個實(shí)例)只能是master或者是slave
  4. master掛了,請求轉(zhuǎn)移到其它master
  5. broker邏輯概念,對應(yīng)1個master/n個slave,cluster(1:n)broker
  6. 先定義master/slave,然后組合出broker(每個broker分配的topic和對應(yīng)的queue的數(shù)量也是一樣的)


    rocketmq架構(gòu).png

2. kafka吞吐量大于rocketmq

kafka在producer端做了數(shù)據(jù)合并,批量發(fā)送,性能是rocketmq的十倍(rocketmq沒有做這層處理)
分區(qū) partition單線程消費(fèi)保證順序性

同一個消費(fèi)組,一個分區(qū)只支持一個消費(fèi)線程來消費(fèi)消息
一個Topic會設(shè)置成多分區(qū)的模式,來支持多個消費(fèi)者
每個生產(chǎn)者自己通過邏輯指定topic 下的partition/queue來保證同一訂單的分區(qū)內(nèi)順序一致

kafka-consumer/producer公用一個文件: 每個topic + partition都會創(chuàng)建一個物理文件,當(dāng)topic變多的時候,消息分散的落盤策略會導(dǎo)致consumer消費(fèi)時磁盤IO競爭激烈成為瓶頸(超過8個topic就會出現(xiàn)抖動)
rocketmq-consumer/producer分開文件: 把producer產(chǎn)生的所有topic所有·queue的消息存儲在一個物理文件commitLog中,邏輯上的劃分,通過異步線程同步ComsuerQueue_n文件 - 只保存commitLog的offset中,consumer消費(fèi)

  • comsuerQueue 是順序讀寫
  • commitLog是順序?qū)?,隨機(jī)讀
  • commitLog/comsuerQueue內(nèi)部保存一個鏈表,通過offset映射到鏈表上的內(nèi)存映射文件(最大2G),進(jìn)行讀取
rocketmq是java編程 -> 大量數(shù)據(jù)gc嚴(yán)重
請求失敗 -> 丟失數(shù)據(jù),但是業(yè)務(wù)卻被告知成功(訂單不接受)
producer都是分布式,請求量不大可能這么大
緩存可以由上層業(yè)務(wù)處理

3. 數(shù)據(jù)可靠性

rocketmq:支持異步實(shí)時刷盤,同步刷盤,同步Replication,異步Replication
kafka:使用異步/同步刷盤,異步/同步Replication,同步下性能極具下降

  • 通過配置ack可以實(shí)現(xiàn)(同步repliacation
  • 缺省Kafka是異步刷盤,調(diào)用 1次/3秒 fsync,可以調(diào)整為(同步刷盤
異步刷盤存 -> 宕機(jī)丟失數(shù)據(jù)(但是在集群情況下,整個集群丟數(shù)據(jù)概率很低)
宕機(jī)機(jī)器恢復(fù) -> 與現(xiàn)有master產(chǎn)生數(shù)據(jù)沖突

4. 消息投遞實(shí)時性

kafka 使用短輪詢,實(shí)時性取決于輪詢間隔時間
rocketmq 使用長輪詢,同push方式實(shí)時性一致,消息的投遞延時通常在幾個毫秒

kafka 0.8版本后支持long pull長輪詢

5. 消息重試機(jī)制/定時消息

kafka 支持消息發(fā)送失敗重試機(jī)制, 但是只能是固定的重試間隔
rocketmq 支持消息發(fā)送失敗重試機(jī)制(可以使用delay定時的嘗試發(fā)送/接收消息,以及嘗試的機(jī)會)

在網(wǎng)絡(luò)抖動等場景下,重試機(jī)制非常重要!!

5. 消息順序性/重復(fù)

多線程中若沒有因果關(guān)系沒有順序。那么用戶在多線程中去發(fā)消息就意味著用戶不關(guān)心那些在不同線程中被發(fā)送的消息的順序。
即多線程發(fā)送的消息,不同線程間的消息不是順序發(fā)布的,同一線程的消息是順序發(fā)布的
kafka 支持消息順序,但是一臺broker宕機(jī)后,就會產(chǎn)生消息亂序當(dāng)然,這個是在kafka使用異步repliacation的情況下
一個consumer只能消費(fèi)一個partition,來保障順序?qū)?/p>

rocketmq 支持嚴(yán)格的消息順序,在順序消息場景下,一臺broker宕機(jī)后,發(fā)送消息會失敗,但是不會亂序
一個consumer可以消費(fèi)多個queue,但一個queue只能由一個consumer消費(fèi)
Listener 接口方法:
MessageListenerOrderly -> 有序
MessageListenerConcurrently ->無序

分區(qū)順序:一個Partition內(nèi)所有的消息按照先進(jìn)先出的順序進(jìn)行發(fā)布和消費(fèi)
全局順序:一個Topic內(nèi)所有的消息按照先進(jìn)先出的順序進(jìn)行發(fā)布和消費(fèi)(topic只有一個分區(qū)的特例)

mysql binlog分發(fā)需要嚴(yán)格的消息順序

消息重復(fù)問題,通過消費(fèi)方冪等來解決

6. 消息查詢

rocketmq 可以根據(jù)messageId查詢消息信息

消息丟失問題非常有幫助(比如丟失訂單,是由于沒有收到信息,還是處理異常)

7. 消息回溯

kafka/rocketmq 都支持offset

總結(jié):典型業(yè)務(wù)場景如consumer做訂單分析,但是由于程序邏輯或者依賴的系統(tǒng)發(fā)生故障等原因,導(dǎo)致今天消費(fèi)的消息全部無效,需要重新從昨天零點(diǎn)開始消費(fèi),那么以時間為起點(diǎn)的消息重放功能對于業(yè)務(wù)非常有幫助

8. 消費(fèi)并行度

kafka 依賴topic配置的分區(qū)數(shù),即消費(fèi)并行度分區(qū)數(shù)一致
rocketmq

  1. 順序消費(fèi)方式并行度同Kafka完全一致
  2. 亂序消費(fèi)方式并行度取決于consumer的線程數(shù)(如topic配置10個隊(duì)列,10臺機(jī)器消費(fèi),每臺機(jī)器100個線程,那么并行度為1000)

8. consumer負(fù)載均衡

kafka:
首先為每個Consumer Group選出了一個Coordinator,所有的Consumer要先找到這個Coordinator,Coordinator從所有Consumer中,選出了一個Master Consumer,讓它負(fù)載分配。它分好之后,把分配結(jié)果傳給其他的Consumer
rocketmq:
consumer主動上報(bào)信息給broker,broker進(jìn)行收集consumer信息,consumer主動獲取broker上topic的consumer group中所有consumer的列表,每個consumer自己計(jì)算對應(yīng)的consumerMessageList

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容