官網-網絡分區html
網絡設備故障致使的網絡分裂。好比,存在A\B\C\D\E五個節點,A\B處於同一子網,B\C\D處於另一子網,中間經過交換機相連。若兩個子網間的交換機故障了即發生了網絡分區,A\B和C\D\E便不能通信。
某些系統是partition-tolerant的,也即,即便發生了網絡分區系統分裂爲了多個子系統,整個系統仍能正常工做。node
RabbitMQ cluster不能很好地處理Network Partition。RabbitMQ將queue、exchange、bindings等信息存儲在Erlang的分佈式數據庫Mnesia中。因此出現Network partition時RabbitMQ的衆多行爲與Mnesia的行爲密切相關。數據庫
若某一node在一段時間內(取決於net_ticktime的設置)不能與另外一node取得聯繫,則Mnesia認爲未能與之取得聯繫的node宕掉了。若兩個node彼此恢復聯繫了,但都曾覺得對方宕掉了,則Manesia判定發生過Network partition。數組
若發生了network partition,cluster中的雙方(或多方)將獨立存在,每一方都將認爲其餘方已經崩潰了。Queues、bindings、exchanges能夠各自獨立的建立、刪除。對於Mirrored queues,處於不一樣network partition的每一方都會擁有各自的master,且各自獨立的讀寫。(也可能發生其餘詭異的行爲)。若network partition恢復了,cluster的狀態並不能自動恢復到network partition發生前的狀態,直至採起措施進行修復。安全
只要cluster中的不一樣node自身沒有失效但之間的通訊發生了中斷均可認爲是發生了Partitions。好比,整個OS的掛起會致使其中的cluster nodes的掛起,但這些nodes卻不認爲自身失效或中止了,而cluster中的其它nodes不能與之取得聯繫,會認爲這些nodes down掉了。舉個例子:若cluster中的一個node運行在筆記本電腦上,合上電腦屏幕就有可能致使node掛起。另外,若cluster中的node運行在虛擬機中,則管理程序可能致使虛擬機掛起,從而使node掛起。網絡
能夠經過rabbitmqctl cluster_status
來查看是否發生了網絡分區
正常的狀態信息:分佈式
[root@rmq-node3 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@rmq-node3' [{nodes,[{disc,['rabbit@rmq-node2','rabbit@rmq-node1']}, {ram,['rabbit@rmq-node3']}]}, {running_nodes,['rabbit@rmq-node1','rabbit@rmq-node2','rabbit@rmq-node3']}, {cluster_name,<<"rabbit@rmq-node1">>}, {partitions,[]}, #注意,這裏爲空數組,代表沒有發生網絡分區 {alarms,[{'rabbit@rmq-node1',[]}, {'rabbit@rmq-node2',[]}, {'rabbit@rmq-node3',[]}]}]
發生網絡分區的狀態信息:this
[root@rmq-node3 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@rmq-node3' [{nodes,[{disc,['rabbit@rmq-node2','rabbit@rmq-node1']}, {ram,['rabbit@rmq-node3']}]}, {running_nodes,['rabbit@rmq-node1','rabbit@rmq-node2','rabbit@rmq-node3']}, {cluster_name,<<"rabbit@rmq-node1">>}, {partitions,[{'rabbit@rmq-node1',['rabbit@rmq-node2','rabbit@rmq-node3']}]}, #這裏是發生了network partitions {alarms,[{'rabbit@rmq-node1',[]}, {'rabbit@rmq-node2',[]}, {'rabbit@rmq-node3',[]}]}]
當發生網絡分區時,會提示以下信息:操作系統
While running in this partitioned state, changes (such as queue or exchange declaration and binding) which take place in one partition will not be visible to other partition(s). Other behaviour is not guaranteed. ==>代表 元數據的改變,不會在節點之間同步
也能夠經過查看日誌找到該問題:日誌
vi /var/log/rabbitmq/rabbit-xxx.log =ERROR REPORT==== 9-Aug-2018::20:15:45 === Mnesia('rabbit@rmq-node2'): ** ERROR ** mnesia_event got {inconsistent_database, starting_partitioned_network, 'rabbit@rmq-node1'}
首先選一個最信任的partition,Mnesia使用該partition中的狀態,其餘partitions中發生的變化都將丟失。
中止其餘partitions中的全部nodes,以後重啓這些nodes。當這些nodes從新加入cluster後將從信任的partition恢復狀態。
最後還需重啓信任的partition中的全部nodes以清除network partition的警告信息
RabbitMQ提供了3種自動處理network partitions的方式:默認爲ignore模式,也即須要手工處理
在pause-minority模式下,察覺其餘nodes down掉後,RabbitMQ將自動暫停認爲本身是少數派的 nodes(例如小於或等於總nodes數的一半),network partition一旦發生,「少數派」的nodes將馬上暫停,直至partition結束後從新恢復。這能夠保證在network partition發生時,至多隻有一個partition中的nodes繼續運行。(犧牲可用性保證一致性)
若全部分區的nodes個數都小於總nodes個數一半,則意味着全部分區的nodes都會認爲本身是少數派,即全部nodes都將暫停;
http://www.rabbitmq.com/partitions.html
在autoheal模式下一旦發生了partition,RabbitMQ將自動肯定一個優勝partition,而後重啓全部不在優勝partition中的nodes。
獲勝的partition爲擁有最多客戶端鏈接的partition(若鏈接相同則爲節點最多的partition)。
關於自動處理partitions的設置在配置文件的cluster_partition_handling參數中進行。
network partitions自動處理並不能保證cluster不出任何問題。
通常來講可做以下選擇:
暫停的nodes上Erlang VM將繼續運行但不監放任何端口或者作其餘工做。它們將每秒檢測一次cluster中的其餘nodes是否可見,若可見則從pause狀態喚醒。 注意: nodes在啓動時不會進入paused狀態,即便是處於「少數派」; RabbitMQ可能會暫停非嚴格意義上的「少數派」中的nodes。如,包含多於總nodes總數一半的nodes。所以在只包含兩個nodes的cluster中使用pause-minority模式並不是好主意,由於在network partition發生或者node失敗時有可能兩個node都會暫停。然而,在包含兩個以上nodes的cluster中pause_minority模式要比ignore更安全; 對於因cluster nodes 掛起引發的partitions pause_minority模式無能爲力。由於掛起的node將不能看到剩餘node是否恢復「可見」,於是不能觸發從cluster中斷開。