RabbitMQ和Kafka的高可用集羣原理

 

前言

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

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

 

RabbitMQ的高可用

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

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

單機模式沒什麼可說的,自己開發練手玩玩就行,我們主要說一下兩種集羣模式的區別。

普通集羣模式

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

整體過程見下圖:

 

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

所以可以得出一個結論,這種模式的集羣根本不能實現高可用,只能通過負載均衡提高一些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 算法

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

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章