天天看點

RabbitMQ腦裂

歡迎支援筆者新作:《深入了解kafka:核心設計與實踐原理》和《rabbitmq實戰指南》,同時歡迎關注筆者的微信公衆号:朱小厮的部落格。

RabbitMQ腦裂

在rabbitmq3.4.x中會出現錯誤的網絡分區檢測(某種意義上可以稱之為腦裂)的現象,本文通過實驗驗證此現象,願小夥伴們少走彎路。

網上有兩篇文章(需要翻牆)

https://groups.google.com/forum/#!topic/rabbitmq-users/dt8vfhmb2zm

https://groups.google.com/forum/#!topic/rabbitmq-users/06oqkytljd8

陳述了腦裂的現象。

文章中描述現象:

michael klishin(rabbitmq-server第二貢獻者)回複:

(根據rabbitmq 3.4.2 release日志:26474 prevent false positive detection of partial partitions (since 3.4.0)) ====》錯誤的網絡分區檢測。

simon macmullen(也是rabbitmq-server的contributor):

自此可以假設:rabbitmq3.4.0存在錯誤的網絡分區檢測,rabbitmq3.4.2修複了此bug。

論證過程:分别對rabbitmq3.4.0, rabbitmq3.4.1, rabbitmq3.4.2, rabbitmq3.6.0進行實驗, 分别配置a b c三個節點組成一個cluster,然後通過停止c的網絡來驗證a和b是否出現錯誤的網絡分區檢測.

rabbitmq版本:3.4.0

rabbitmq節點配置

共三個節點:a b c,分别為:

a:rabbit@zhuzhonghua2-fqawb

b:rabbit@hiddenzhu-8drd

c:rabbit@hidden-local

b join_cluster a; c join_cluster a

檢視cluster_status:(rabbitmqctl cluster_status)

在c節點執行service network stop

在a節點檢視cluster_status

再次在a節點檢視cluster_status

結論:【這裡出現了網絡分區,但是真正的網絡分區是要在網絡恢複連通之後才能檢測】

在c節點執行service network start

檢視a節點cluster_status

檢視b節點cluster_status

檢視c節點cluster_status

rabbitmq版本:3.4.1

節點配置如上(b join_cluster a, c join_cluster a)

檢視節點狀态:

結論:【複現】

rabbitmq版本:3.4.2 (版本3.6.0與此相同)

檢視節點狀态

結論:【未複現】

版本問題基本得到驗證,為了防止錯誤的網絡分區檢測現象,建議正在使用rabbitmq的小夥伴更新,避免使用3.4.0和3.4.1這兩個版本。

有關網絡分區有篇文章(​​rabbitmq 網絡分區問題​​)這樣介紹:

rabbitmq 叢集的網絡分區容錯性并不是非常高,在網絡經常發生分區時會有些問題,最明顯的就是腦裂問題。

官方文檔是這樣介紹的:

從中我們可以看出,在廣域網環境下不應該使用叢集,而應該使用 federation 或者 shovel 來解決。

不過即使是在區域網路環境下,網絡分區也不可能完全避免,網絡裝置(比如中繼裝置、網卡)出現故障也會導緻網絡分區。

當出現網絡分區時,不同分區裡的節點會認為不屬于自身所在分區的節點都已經挂了,對 queue、exchange、binding 的操作僅對目前分區有效。在 rabbitmq 的預設配置下,即使網絡恢複了也不會自動處理網絡分區帶來的問題進而恢複叢集。rabbitmq(3.1+)會自動探測網絡分區,并且提供了配置來解決這個問題。

rabbitmq 提供了4種配置(詳細參考:

ignore:預設配置,發生網絡分區時不作處理,當認為網絡是可靠時選用該配置

autoheal:各分區協商後重新開機用戶端連接配接最少的分區節點,恢複叢集(cap 中保證 ap,有狀态丢失)

pause_if_all_down。

pause_minority:分區發生後判斷自己所在分區内節點是否超過叢集總節點數一半,如果沒有超過則暫停這些節點(保證 cp,總節點數為奇數個)

參考:

● ​​rabbitmq 官方文檔​​

● ​​網絡分區​​

● ​​腦裂問題​​

RabbitMQ腦裂