• 记一次【RabbitMQ集群网络分区】的问题,以及网络分区时的影响范围和如何恢复


    记一次【RabbitMQ集群网络分区】的问题,以及网络分区时的影响范围和如何恢复

    一、集群节点信息

    172.29.40.101(rabbitmq-1172.29.40.102(rabbitmq-2172.29.40.103(rabbitmq-3
    • 1
    • 2
    • 3

    二、如何确定集群发生了网络分区?

    1)RabbitMQ 集群发生网络分区时,RabbitMQ Management UI管理平台上,overview概览页面会显示如下告警提示:
    在这里插入图片描述

    可以明确看到发生分区的节点:
    The nature of the partition is as follows:

    NodeWas partitioned from
    rabbit@rabbitmq-3rabbit@rabbitmq-1

    2)我们可以登录到rabbit@rabbitmq-3对应的机器上,

    cd /usr/local/rabbitmq_server-3.5.6/sbin
    ./rabbitmqctl cluster_status
    
    • 1
    • 2

    在这里插入图片描述
    在这里插入图片描述

    三、什么是集群网络分区?

    集群和网络分区问题,一般指集群节点之间出现了网络故障。
    RabbitMQ集群可用于实现不同的目标:通过节点间数据镜像复制以提高数据的安全性、提高客户端操作的可用性、提高整体吞吐量等。如果集群成员节点之间的网络连接发生故障,会影响客户端操作的数据一致性和可用性(CAP 定理)。由于不同的应用程序对一致性有不同的要求,并且可以不同程度地容忍不可用,因此可以使用不同的 分区处理策略。

    四、集群网络分区如何检测?

    RabbitMQ集群的一个节点,如果另一个节点在一段时间内(默认60秒)无法联络它,那么当前节点会确定与其对等的节点是否已经宕机。如果两个节点重新建立了联系,并且双方都认为对方已宕机,那么当前节点将确定为已经发生了分区。发生分区的节点服务器上,查看RabbitMQ日志:

    [root@rabbitmq-3 rabbitmq]#cd /usr/local/rabbitmq_server-3.5.6/var/log/rabbitmq
    [root@rabbitmq-3 rabbitmq]# tail -100f rabbit\@rabbitmq-3.log
    
    • 1
    • 2

    可以看到分区的日志记录:

    =ERROR REPORT==== 3-Aug-2022::18:10:31 ===
    Mnesia('rabbit@rabbitmq-3'): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, 'rabbit@rabbitmq-1'}
    
    • 1
    • 2

    五、网络分区期间的行为

    当网络分区存在时,集群中发生网络分区的两个(或更多)节点都可以独立演化,因为此时双方都认为对方已经崩溃了。这种情况被称为脑裂。队列、绑定关系、交换机均可以单独创建或删除。

    跨分区拆分的经典镜像队列最终将在分区的每一侧都有一个领导者,双方各自独立运行。但是官方有说明,经典镜像队列将在未来移除,改用仲裁队列模式。

    除非配置了分区处理策略,例如pause_minority,否则即使网络连接恢复,集群的拆分也仍将继续。

    六、由挂起和恢复引起的分区

    我们所说的集群“网络”分区,实际上指的是在集群中没有任何节点发生任何故障的情况下,集群中的不同节点间发生了通信中断的现象。

    除了网络故障,对正在运行的集群节点,挂起和恢复操作系统也可能导致分区。因为挂起的节点不会认为自己失败,甚至停止,但集群中的其他节点会认为它已经分区了。这种情况最常见原因是虚拟机被挂起导致的(例如将虚拟机从一台宿主机迁移到另一台宿主机)。

    由虚拟机挂起和恢复操作引起的分区,往往是不对称的 - 挂起的节点不一定会看到其他节点已关闭,但会被集群的其他节点视为已关闭。这对pause_minority模式有特别的影响。

    七、集群发生网络分区时,它们的影响是什么以及该如何恢复?

    从脑裂中恢复

    要从脑裂中恢复,首先需要选择一个我们最信任的分区,该分区将成为系统状态(模式、消息)使用的权限;在其他分区上发生的任何更改都将丢失。

    停止其他分区中的所有节点,然后重新启动它们。当他们重新加入集群时,他们将从受信任的分区恢复状态。

    最后,我们还应该重新启动受信任分区中的所有节点以清除警告。

    停止整个集群并重新启动,这个操作可能更简单。注意,如果选择这样操作,请确保启动的第一个节点所在的分区是受信任的分区。

    还未导致脑裂前恢复

    解决思路:从mq集群中选取一个主节点,然后重启从节点的mq服务。
    问题解决:

    1. 在集群每个节点的vm中分别运行:lsof -nP -i:5672 |wc -l
    2. 选取其中数量最大的当选为主节点(当然如果明确知道未发生分区的节点,可以只选选用当做主节点)。然后重新启动从节点服务。若从节点服务重新启动失败,运行命令强制重启:./rabbitmqctl force_boot
    3. 如果 ./rabbitmqctl force_boot 命令依然停不掉服务,可以暴力停止:
    netstat -nplt | grep beam
    kill -9 pid
    
    • 1
    • 2
    1. 重新启动服务:./rabbitmq-server -detached
    2. 主节点最好也重启一下。
    3. 执行:./rabbitmqctl cluster_status,出现 {partitions,[]}] 字样,集群分区得到恢复。

    分区处理策略

    RabbitMQ 还提供了三种自动处理网络分区的方法:

    1. pause-minority模式
    2. pause-if-all-down 模式
    3. autoheal模式

    默认ignore模式。

    在pause-minority模式下,RabbitMQ会在其他节点宕机后,自动暂停那些被判定为少数派的集群节点(即小于或等于集群节点总数的一半)。因此,它从CAP定理中选择了分区容忍而不是可用性。这可以确保在发生网络分区时,单个分区中的最多节点将继续运行。少数节点将在分区开始时立即暂停,并在分区结束时再次开始。这种配置可以防止脑裂,因此能够自动恢复。

    在pause-if-all-down模式下,RabbitMQ会自动暂停那些无法访问列表中任何节点的集群节点。换句话说,RabbitMQ必须关闭所有列出的节点才能暂停集群节点。

    在autoheal模式下,如果一个分区被认为发生了,RabbitMQ会自动决定哪个分区获胜(获胜的分区是拥有最多客户端连接的分区),并重启所有不在这个分区中的节点。


    我们可以在rabbitmq配置文件:rabbitmq.config 中,修改配置参数cluster_partition_handling指定使用哪种分区策略:

    /usr/local/rabbitmq_server-3.5.6/etc/rabbitmq/rabbitmq.config
    
       %% How to respond to cluster partitions.
       %% See http://www.rabbitmq.com/partitions.html for further details.
       %% 可选:autoheal、pause_minority、pause_if_all_down
       %% {cluster_partition_handling, ignore},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果使用pause_if_all_down模式,则需要附加参数:

    • nodes: nodes which should be unavailable to pause
    • recover: recover action, can be ignore or autoheal

    例如:

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    8、选择哪种分区策略模式?

    • ignore:当网络可靠性实际上可能最高且节点可用性最重要时使用。例如,集群所有节点都部署在了同一个机器上,连接一个交换机,该交换机也是通往外界的路由。
    • pause_minority:适用于在单个区域中跨机器或可用区域进行集群时,一次丢失大多数节点(区域)的概率被认为非常低。如果/当丢失的节点回来时,这种模式会牺牲一些可用性来自动恢复。
    • autoheal:适用于更关注服务连续性而不是节点间数据一致性的情况。

    参考官方文档:https://www.rabbitmq.com/partitions.html

  • 相关阅读:
    Hadoop实战——MapReduce-字符统计(超详细教学,算法分析)
    python 异常
    ubuntu安装ROS
    web前端-javascript-基本数据类型和引用数据类型(对象和基本数据类型保存到栈内存,对象保存在堆内存,比较两个基本数据类型或引用数据类型)
    virtualBox虚拟机安装多个+主机访问虚拟机+虚拟机访问外网配置
    SpringMVC
    python基础-面向对象
    【探索Spring底层】7.AOP增强
    JEECG shiro验证实现分析
    项目知识点总结-过滤器-MD5注册-邮箱登录
  • 原文地址:https://blog.csdn.net/want_you_gogo/article/details/126147452