歡迎支援筆者新作:《深入了解kafka:核心設計與實踐原理》和《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 官方文檔
● 網絡分區
● 腦裂問題