簡述RabbiMQ和KafKa的高可用

如何保證消息隊列的高可用


前段時間有一個非常大的互聯網公司,非常核心的系統,就是疏忽了MQ,沒考慮MQ如何保證高可用,如果MQ掛了怎麼辦,導致幾個小時系統不可用,公司損失幾千萬!足以見得高可用是架構設計必須考慮的問題!

RabbitMQ的高可用
rabbitmq支持三種模式:單機模式,普通集羣模式,鏡像集羣模式

  • 單機模式
    單機模式就是demo級別的,一般就是你本地啓動了玩玩兒的,沒人生產用單機模式

  • 普通集羣模式
    普通集羣模式的意思就是在多臺機器上啓動多個rabbitmq實例,每個機器啓動一個。但是你創建的queue,只會放在一個rabbtimq實例上,但是每個實例都同步queue的元數據。完了你消費的時候,實際上如果連接到了另外一個實例,那麼那個實例會從queue所在實例上拉取數據過來。

    這種方式確實很麻煩,也不怎麼好,沒做到所謂的分佈式,就是個普通集羣。因爲這導致你要麼消費者每次隨機連接一個實例然後拉取數據,要麼固定連接那個queue所在實例消費數據,前者有數據拉取的開銷,後者導致單實例性能瓶頸。

    而且如果那個放queue的實例宕機了,會導致接下來其他實例就無法從那個實例拉取,如果你開啓了消息持久化,讓rabbitmq落地存儲消息的話,消息不一定會丟,得等這個實例恢復了,然後纔可以繼續從這個queue拉取數據。

    所以這個事兒就比較尷尬了,這就沒有什麼所謂的高可用性可言了,這方案主要是提高吞吐量的,就是說讓集羣中多個節點來服務某個queue的讀寫操作。

  • 鏡像集羣模式
    這種模式,纔是所謂的rabbitmq的高可用模式,跟普通集羣模式不一樣的是,你創建的queue,無論元數據還是queue裏的消息都會存在於多個實例上,然後每次你寫消息到queue的時候,都會自動把消息到多個實例的queue裏進行消息同步。

    這樣的話,好處在於,你任何一個機器宕機了,沒事兒,別的機器都可以 用。壞處在於,第一,這個性能開銷也太大了吧,消息同步所有機器,導致網絡帶寬壓力和消耗很重!第二,這麼玩兒,就沒有擴展性可言了,如果某個queue負載很重,你加機器,新增的機器也包含了這個queue的所有數據,並沒有辦法線性擴展你的queue

    那麼怎麼開啓這個鏡像集羣模式呢?我這裏簡單說一下,避免面試人家問你你不知道,其實很簡單rabbitmq有很好的管理控制檯,就是在後臺新增一個策略,這個策略是鏡像集羣模式的策略,指定的時候可以要求數據同步到所有節點的,也可以要求就同步到指定數量的節點,然後你再次創建queue的時候,應用這個策略,就會自動將數據同步到其他的節點上去了。

kafka的高可用性

  • kafka的HA機制
    kafka一個最基本的架構認識:多個broker組成,每個broker是一個節點;你創建一個topic,這個topic可以劃分爲多個partition,每個partition可以存在於不同的broker上,每個partition就放一部分數據。

    這就是天然的分佈式消息隊列,就是說一個topic的數據,是分散放在多個機器上的,每個機器就放一部分數據。

    實際上rabbitmq之類的,並不是分佈式消息隊列,他就是傳統的消息隊列,只不過提供了一些集羣、HA的機制而已,因爲無論怎麼玩兒,rabbitmq一個queue的數據都是放在一個節點裏的,鏡像集羣下,也是每個節點都放這個queue的完整數據。

    kafka 0.8以前,是沒有HA機制的,就是任何一個broker宕機了,那個broker上的partition就廢了,沒法寫也沒法讀,沒有什麼高可用性可言。

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

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

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

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

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