首頁>技術>

寫在前面:目前主流的MQ產品有ActiveMQ、RabbitMQ、RocketMQ、Kafka...

其適用場景很多,但是比較核心的有 3 個:解耦、非同步、削峰

解耦:毋庸置疑就是減少系統間耦合度,避免系統間相互(強)依賴(Pub/Sub釋出訂閱訊息模型)。

非同步:提高請求效率,減少響應時間,對於無事務操作依賴和資料實時性情況,可接收請求即返回使用者,將請求放入訊息佇列處理。

削峰:基於非同步特性,在特定業務場景下,解決了請求一擁而上全部湧入DB會導致DB系統崩潰問題。

訊息佇列也存在一些缺點,如下:

系統可用性降低系統複雜度提高一致性問題RabbitMQ 的高可用性

基於主從(非分散式)高可用性,三種模式:單機模式、普通叢集模式、映象叢集模式。

1、單機模式

2、普通叢集模式

就是在多臺機器上啟動多個rabbitmq例項,每個機器啟動一個。但是你建立的queue,只會存放在一個rabbtimq例項上,但是每個例項都同步queue的元資料。實際上如果連線到了另外一個例項,那麼那個例項會從真正存有資料的queue所在例項上拉取資料過來。

沒做到所謂的分散式,就是個普通叢集。該方案主要是提高吞吐量的,就是說讓叢集中多個節點來服務某個queue的讀寫操作。

3、映象叢集模式

這種模式,才是所謂的rabbitmq的高可用模式,跟普通叢集模式不一樣的是,你建立的queue,無論元資料還是queue裡的訊息都會存在於多個例項上,然後每次你寫訊息到queue的時候,都會自動把訊息到多個例項的queue裡進行訊息同步。

Kafka的高可用

由多個broker組成,每個broker就是一個節點。

建立一個topic,這個topic可以劃分為多個partition,每個partition可以存在於不同的broker上,每個partition存放放一部分資料。

kafka就是一個分散式訊息佇列,就是說一個topic的資料,是分散放在多個機器上的,每個機器就放一部分資料。

kafka 0.8以後,提供了HA機制,就是replica副本機制。每個partition的資料都會同步到其他機器上,形成自己的多個replica副本。然後所有replica會選舉一個leader出來,那麼生產和消費都跟這個leader打交道,然後其他replica就是follower。寫的時候,leader會負責把資料同步到所有follower上去,讀的時候就直接讀leader上資料即可。只能讀寫leader?很簡單,要是你可以隨意讀寫每個follower,那麼就要care資料一致性的問題,系統複雜度太高,很容易出問題。kafka會均勻地將一個partition的所有replica分佈在不同的機器上,這樣才可以提高容錯性。

  kafka的這種機制,就有所謂的高可用性了,因為如果某個broker宕機了,也沒事兒,因為那個broker上面的partition在其他機器上都有副本的,那麼此時會重新選舉一個新的leader出來,大家繼續讀寫那個新的leader即可。這就有所謂的高可用性了。

所有的生產者請求和消費者請求都經過leader副本,leader副本以外的副本都是follower副本,follower副本不處理來自客戶端的請求,它們唯一的任務就是從leader副本那裡複製訊息,保持與leader副本一致的狀態。如果leader 副本發生崩潰,其中的一個follower副本會被提升為新的leader副本。

那麼符合哪些條件的follower副本才可以成為leader副本呢?答案是“同步副本”。

leader會跟蹤與其保持同步的副本列表,該列表稱為ISR(即in-sync Replica)。如果一個follower宕機,或者落後太多,leader將把它從ISR中移除。這裡所描述的“落後太多”指Follower複製的訊息落後於Leader後的條數超過預定值(該值可在server.properties中透過replica.lag.max.messages配置,其預設值是4000)或者Follower超過一定時間(該值可在server.properties中透過replica.lag.time.max.ms來配置,其預設值是10000)未向Leader傳送fetch請求。

1)寫過程

  寫資料的時候,生產者就寫leader,然後leader將資料落地寫本地磁碟,接著其他follower自己主動從leader來pull資料。一旦所有follower同步好資料了,就會發送ack給leader,leader收到所有follower的ack之後,就會返回寫成功的訊息給生產者。(當然,這只是其中一種模式,還可以適當調整這個行為)

2)讀過程

  消費的時候,只會從leader去讀,但是隻有當一個訊息已經被所有follower都同步成功並返回ack的時候,這個訊息才能夠被消費者讀到。

參考:https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/how-to-ensure-high-availability-of-message-queues.md

內容有參考,有自己的思考和總結,修行之路源於記錄和不斷地學習

12
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Java記憶體模型(JMM)詳解