官网-网络分区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中断开。