RabbitMQ和Kafka的高可用集羣原理

 

前言

小夥伴們,經過前邊文章的閱讀,相信你們已經對RocketMQ的基本原理有了一個比較深刻的瞭解,那麼你們對當前比較經常使用的RabbitMQ和Kafka是否是也有興趣瞭解一些呢,瞭解的多一些也不是壞事,面試或者跟人聊技術的時候也會讓你更有話語權嘛。面試

那王子今天就跟你們聊一聊RabbitMQ和Kafka在處理高可用集羣時的原理,看看它們與RocketMQ有什麼不一樣。小夥伴們能夠從新溫習一下常見的消息中間件有哪些?大家是怎麼進行技術選型的?這篇文章,瞭解一下他們之間的區別。算法

 

RabbitMQ的高可用

以前咱們的文章講過,RabbitMQ是ActiveMQ的一個很好的替代產品,它是基於主從實現的高可用集羣,但它是非分佈式的。架構

RabbitMQ一共有三種模式:單機模式、普通集羣模式、鏡像集羣模式負載均衡

單機模式沒什麼可說的,本身開發練手玩玩就行,咱們主要說一下兩種集羣模式的區別。分佈式

普通集羣模式大數據

普通集羣模式,其實就是將RabbitMQ 部署到多臺機器上,每一個機器啓動一個,它們之間進行消息通訊。你建立的 queue,只會放在一個 RabbitMQ 的實例上,其餘的實例會同步 queue 的元數據(元數據裏包含有 queue 的一些配置信息,經過元數據,能夠找到 queue 所在的位置)。你消費的時候,實際上若是鏈接到了另一個實例,那麼那個實例會經過元數據定位到 queue 所在的位置,而後訪問queue所在的實例,拉取數據過來發送給消費者。設計

總體過程見下圖:中間件

 

這種方式很麻煩,只是一個普通的集羣,並且數據並無副本,只存儲在了一臺機器上,只要真實存儲數據的機器宕機,系統直接崩潰,由於沒有數據能夠獲取了。blog

因此能夠得出一個結論,這種模式的集羣根本不能實現高可用,只能經過負載均衡提升一些MQ的吞吐量,生成環境下是不會使用的。隊列

鏡像集羣模式

那麼真正用於生產環境,實現高可用的方式是什麼呢?沒錯就是接下來要說的鏡像集羣模式。

它和普通集羣模式最大的區別在於,queue數據和原數據再也不是單獨存儲在一臺機器上,而是同時存儲在多臺機器上。也就是說每一個RabbitMQ實例都有一份鏡像數據(副本數據)。每次寫入消息的時候都會自動把數據同步到多臺實例上去,這樣一旦其中一臺機器發生故障,其餘機器還有一份副本數據能夠繼續提供服務,也就實現了高可用。

整個過程看下圖:

 

那麼如何開啓鏡像集羣模式呢?

RabbitMQ是有強大的管理控制檯的,經過管控臺能夠很容易的配置,具體操做自行百度吧,咱們本篇的目的是弄懂原理。

對於通常小型公司,小型項目來說,這套架構已經能夠支持了,可是對於海量大數據的要求,若是每臺機器都要有一份鏡像副本,並且互相之間還要不停的同步數據,它是很難支持的,由於它不是分佈式的。因此咱們仍是使用RocketMQ吧。

 

Kafka的高可用

再來聊聊Kafka的高可用,再聊高可用以前,咱們先要簡單瞭解下它的基本架構。

它是由多個Broker組成的,每一個Broker都是一個節點,小夥伴們是否是想到了RocketMQ的Broker呢。當咱們建立Topic的時候,這個Topic是會劃分紅多個partition的,每一個partition又能夠存在不一樣的Broker上,這裏的每一個partition都會放一部分數據,能夠把它理解成一個分片。

因而可知,Kafka是一個自然的分佈式消息隊列,它的Topic是分紅多個partition分佈到多個Broker上存儲的。

既然講到這裏,可能有不少小夥伴會好奇RocketMQ的Topic是怎麼存儲的呢?難道RocketMQ的Topic就不會分片了嗎?

答案是否認的,RocketMQ也是借鑑了Kafka分片存儲的機制,引入了一個新的概念ConsumeQueue用來代替partition,原先kafka,裏面partition存儲的是整個消息,可是如今ConsumeQueue裏面是存儲消息的存儲地址,可是不存儲消息了。如今每一個ConsumeQueue存儲的是每一個消息在commitlog這個文件的地址,可是消息存在於commitlog中。
也就是全部的消息體都寫在了一個文件裏面,每一個ConsumeQueue只是存儲這個消息在commitlog中地址。

好了,有關RocketMQ的原理咱們以後再單獨講解,如今咱們繼續看Kafka的高可用實現。

Kafka 0.8 之後,才正式開始支持高可用的,它提供了 HA 機制,就是 replica(複製品) 副本機制。每一個 partition 的數據都會同步到其它機器上,造成本身的多個 replica 副本。全部 replica 會選舉一個 leader 出來,那麼生產和消費都跟這個 leader 打交道,而後其餘 replica 就是 follower。寫的時候,leader 會負責把數據同步到全部 follower 上去,讀的時候就直接讀 leader 上的數據便可。只能讀寫 leader?很簡單,要是你能夠隨意讀寫每一個 follower,那麼就要 考慮數據一致性的問題,系統複雜度過高,很容易出問題。Kafka 會均勻地將一個 partition 的全部 replica 分佈在不一樣的機器上,這樣才能夠提升容錯性。

咱們看一下下圖,就是Kafka的高可用原理:

 

這樣的一套架構下,Kafka就實現高可用了。由於若是某個Broker掛掉了,他的partition在其餘Broker中都有副本。若是掛掉的Broker上有某個 partition 的 leader,那麼此時會從 follower 中從新選舉一個新的 leader 出來,你們繼續讀寫那個新的 leader 便可。這就有所謂的高可用性了。

寫數據的時候,生產者就向 leader寫數據,而後 leader 將數據落地寫本地磁盤,接着其餘 follower 本身主動從 leader 來 pull 數據。一旦全部 follower 同步好數據了,就會發送 ack 給 leader,leader 收到全部 follower 的 ack 以後,就會返回寫成功的消息給生產者。(固然,這只是其中一種模式,還能夠適當調整這個行爲)

消費的時候,只會從 leader 去讀,可是隻有當一個消息已經被全部 follower 都同步成功返回 ack 的時候,這個消息纔會被消費者讀到。

 

總結

好了,說了這麼多,我相信小夥伴們對於RabbitMQ和Kafka的高可用集羣原理必定會有個很深的認識了吧。那王子給你們留下一個思考題,如今你能本身說出RabbitMQ、Kafka、RocketMQ的高可用集羣有什麼不一樣了嗎?

今天的分享就到這裏,歡迎你們持續閱讀王子的消息中間件專輯,一塊兒閒談消息中間件的裏裏外外吧。

 

往期文章推薦:

中間件專輯:

什麼是消息中間件?主要做用是什麼?

常見的消息中間件有哪些?大家是怎麼進行技術選型的?

你懂RocketMQ 的架構原理嗎?

聊一聊RocketMQ的註冊中心NameServer

Broker的主從架構是怎麼實現的?

RocketMQ生產部署架構如何設計

算法專輯:

和同事談談Flood Fill 算法

詳解股票買賣算法的最優解(一)

詳解股票買賣算法的最優解(二)

相關文章
相關標籤/搜索