1. 程式人生 > >RabbitMQ 集群與網絡分區(理論知識)

RabbitMQ 集群與網絡分區(理論知識)

ec2 mas 修復 場景 可用 chan 將不 屏幕 AR

關於network partition

網絡設備故障導致的網絡分裂。比如,存在A\B\C\D\E五個節點,A\B處於同一子網,B\C\D處於另外一子網,中間通過交換機相連。若兩個子網間的交換機故障了即發生了網絡分區,A\B和C\D\E便不能通訊。
某些系統是partition-tolerant的,也即,即使發生了網絡分區系統分裂為了多個子系統,整個系統仍能正常工作。

RabbitMQ cluster不能很好地處理Network Partition。RabbitMQ將queue、exchange、bindings等信息存儲在Erlang的分布式數據庫Mnesia中。所以出現Network partition時RabbitMQ的眾多行為與Mnesia的行為密切相關。

Network Partition的檢測


若某一node在一段時間內(取決於net_ticktime的設置)不能與另一node取得聯系,則Mnesia認為未能與之取得聯系的node宕掉了。若兩個node彼此恢復聯系了,但都曾以為對方宕掉了,則Manesia斷定發生過Network partition。

發生Network Partition後RabbitMQ的行為
若發生了network partition,cluster中的雙方(或多方)將獨立存在,每一方都將認為其他方已經崩潰了。Queues、bindings、exchanges可以各自獨立的創建、刪除。對於Mirrored queues,處於不同network partition的每一方都會擁有各自的master,且各自獨立的讀寫。(也可能發生其他詭異的行為)。若network partition恢復了,cluster的狀態並不能自動恢復到network partition發生前的狀態,直至采取措施進行修復。

由suspend/resume引起的 partitions

只要cluster中的不同node自身沒有失效但之間的通信發生了中斷都可認為是發生了Partitions。比如,整個OS的掛起會導致其中的cluster nodes的掛起,但這些nodes卻不認為自身失效或停止了,而cluster中的其它nodes不能與之取得聯系,會認為這些nodes down掉了。舉個例子:若cluster中的一個node運行在筆記本電腦上,合上電腦屏幕就有可能導致node掛起。另外,若cluster中的node運行在虛擬機中,則管理程序可能導致虛擬機掛起,從而使node掛起。

如何從network partition中恢復
首先選一個最信任的partition,Mnesia使用該partition中的狀態,其他partitions中發生的變化都將丟失。
停止其他partitions中的所有nodes,之後重啟這些nodes。當這些nodes重新加入cluster後將從信任的partition恢復狀態。
最後還需重啟信任的partition中的所有nodes以清除network partition的警告信息

RabbitMQ自動處理partitions

RabbitMQ提供了兩種自動處理network partitions的方式:pause-minority模式和autoheal模式(默認為ignore模式,也即需要手工處理)
在pause-minority模式下,察覺其他nodes down掉後RabbitMQ將自動暫停認為自己是少數派的 nodes(例如小於或等於總nodes數的一半),network partition一旦發生,“少數派”的nodes將立刻暫停,直至partition結束後重新恢復。這可以保證在network partition發生時,至多只有一個partition中的nodes繼續運行。(犧牲可用性保證一致性)

在autoheal模式下一旦發生了partition,RabbitMQ將自動確定一個優勝partition,然後重啟所有不在優勝partition中的nodes。獲勝的partition為擁有最多客戶端連接的partition(若連接相同則為節點最多的partition)。關於自動處理partitions的設置在配置文件的cluster_partition_handling參數中進行。

兩種自動處理partitions模式的適用場景
network partitions自動處理並不能保證cluster不出任何問題。一般來說可作如下選擇:
ignore:若網絡非常可靠。所有nodes在同一機架,通過交換機連接,該交換機也是通往外部網絡的出口。在cluster的某一部分故障時不希望其余部分受影響。或者cluster只有兩個node。
pause_minority:網絡較不可靠。cluster處於EC2的3個AZ中,假定每次至多只有其中一個AZ故障,想要剩余的AZ繼續提供服務而故障的AZ中的nodes在AZ恢復後重新自動加入到cluster。
autoheal:網絡很不可靠。與數據完整性相比更關註服務的持續性。cluster只有兩個node。

關於pause-minority模式
暫停的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中斷開。

RabbitMQ 集群與網絡分區(理論知識)