概述
集群成员之间的网络连接故障会影响客户端操作的数据一致性和可用性(如CAP定理)。 由于不同的应用程序对一致性有不同的要求 并且可以容忍不同程度的不可用,可以使用不同的分区处理策略。
检测网络分区
节点确定其对等节点是否关闭,如果另一个节点关闭节点在一段时间内无法联系它,默认为60 秒。 如果两个节点重新接触,并且都认为另一个节点已关闭,则节点将确定已发生分区。这将写入 RabbitMQ 日志,其形式如下:
bash
2020-05-18 06:55:37.324 [error] <0.341.0> Mnesia(rabbit@warp10): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, rabbit@hostname2}
可以通过服务器日志、HTTP API(用于监控)和 CLI 命令来识别分区是否存在。
CLI命令查看网络分区
bash
rabbitmq-diagnostics cluster_status
rabbitmq-diagnostics cluster_status
通常会显示 分区的空列表,如果发生网络分区将会显示Node节点:
bash
rabbitmqctl cluster_status
# => Cluster status of node rabbit@warp10 ...
# => Basics
# =>
# => Cluster name: local.1
# =>
# => ...edited out for brevity...
# =>
# => Network Partitions
# =>
# => Node flopsy@warp10 cannot communicate with hare@warp10
# => Node rabbit@warp10 cannot communicate with hare@warp10
Http API查看网络分区
get方式请求/api/nodes
接口,将返回分区 "在结点"下的每个节点的信息。
网络分区期间的行为
当网络分区就位时,两端(或更多!)的集群可以独立演化,两边以为对方已经崩溃了。这种情况称为裂脑。队列、绑定、交换可以单独创建或删除。
仲裁队列将在多数派。少数端的仲裁队列副本将不再存在取得进展(即接受新消息、交付给消费者等),所有这些工作都将是由新领导完成。
跨分区拆分的经典镜像队列最终将得到隔板的每一侧各有一个引线,同样是两侧独立行动。
除非分区处理策略,如pause_minority,配置为使用,即使在网络连接恢复后,拆分仍将继续。
脑裂恢复
要从裂脑中恢复,首先选择一个分区你最信任的。此分区将成为系统状态(架构、消息)的权限使用;在其他分区上发生的任何更改都将丢失。
停止其他分区中的所有节点,然后启动所有节点再。当他们重新加入集群时,他们将从受信任分区恢复状态。
最后,您还应该重新启动受信任的所有节点partition以清除警告。
停止整个集群并重新启动它可能更简单;如果是这样,请确保您启动的第一个节点来自受信任的分区。
分区处理策略
RabbitMQ 还提供了三种处理网络分区的方法:
- pause_minority:发生分区后,会自动关闭处于少数分区的节点,并在网络恢复后自动重新加入。注意:这种模式下,需要rabbitmq的节点数量应为奇数(如3个或者5个)
- autoheal:发生分区后,各分区下的节点正常工作,网络恢复后,会选出一个连接数最多、分区内节点数最多的节点为winner节点, 并重启其他节点,其他节点从winner节点同步数据。
- pause-if-all-down:在关注的节点全部下线后会关闭自己,在关注的节点上线后, 可以有两种选择:
- ignore: 不做任何处理
- autoheal: 通过autoheal机制来恢复
如果不配置,则代表忽略网络分区,不做任何处理。
修改方式
-
进入rabbitmq安装目录(如 /opt/rabbitmq/)
-
找到配置文件:一般在 安装目录 + rabbitmq-${版本}/etc/rabbitmq/rabbitmq.conf
-
如果能搜到关键字:"cluster_partition_handling" 则直接修改对应的值为上面选项中的一个,如果没有搜到,则说明采用了忽略网络分区模式,可添加相关配置
示例如下:
pause-minority模式
bash
cluster_partition_handling=pause_minority
pause-minority模式
bash
cluster_partition_handling=autoheal
pause-if-all-down模式
bash
cluster_partition_handling = pause_if_all_down
## Recovery strategy. Can be either 'autoheal' or 'ignore'
cluster_partition_handling.pause_if_all_down.recover = ignore
## Node names to check
cluster_partition_handling.pause_if_all_down.nodes.1 = rabbit@myhost1
cluster_partition_handling.pause_if_all_down.nodes.2 = rabbit@myhost2
策略选择
-
ignore:在网络可靠性达到最高实际可能的情况下使用节点可用性是最重要的。例如,所有群集节点都可以位于同一机架或等效机架中,与交换机连接,该交换机也是路由对外界。
-
pause_minority:适用于跨机架或可用区群集时在单个区域中,并且丢失大多数节点(区域)的概率一次被认为是非常低的。此模式会牺牲一些可用性。如果/当丢失的节点恢复时自动恢复的能力。
-
autoheal:当更关注服务的连续性时而不是跨节点的数据一致性。