RabbitMQ 与脑裂问题

2016-07-11 09:22:04   最后更新: 2016-07-11 09:22:04   访问数量:2028




上面几篇日志中,我们一步步地搭建、配置了 rabbitmq,经过在此之前的应用介绍,我们已经可以搭建一个相对复杂的多节点分布式生产-消费的分布式应用模型了

rabbitmq 实战

本篇日志中,主要介绍一下 rabbitmq 的网络问题

 

RabbitMQ 集群的网络分区容错性并不高,在网络质量较差的环境中会比较容易出现问题,其中最明显的就是脑裂问题

 

 

所谓的脑裂问题,就是在多机热备的高可用 HA 系统中,当两个节点心跳突然断开,就分裂为了两个独立的个体,由于互相失去联系,都认为对方出现了故障,因此都会去争抢对方的资源,争抢启动,由此就会发生严重的后果

举个形象的例子,A 和 B 作为一个双机热备集群的两个节点,各自持有集群的一部分数据 -- a 和 b,这时,两机器之间突然无法通信,A 认为 B 已经挂掉,B 认为 A 已经宕机,于是会出现:

  1. 如果 A 拥有 b 数据的备份,则 A 将以完整数据运行,B 也同样以完整数据运行,这将很可能导致两个节点同时读写共享数据造成数据损坏
  2. 如果 A、B 各自仅拥有 a、b 数据,那么两个节点要么均无法启动,要么以瓜分完整共享数据的方式启动

总之,无论是哪一种,都不是我们希望见到的

因此,在 RabbitMQ 官方文档中,明确建议了,不要在广域网环境下使用,否则,应该使用 federation 或者 shovel 插件

 

当然,我们不能要求集群的可用性或网络的健康达到 100%,即使在局域网中,发生故障的可能性也是存在的

RabbitMQ 3.1 以上版本提供了配置来解决这个问题:

[ {rabbit, [{tcp_listeners,[5672]}, {cluster_partition_handling, ignore}] } ].

 

 

RabbitMQ 提供了三种配置:

  1. ignore:默认配置,发生网络分区时不作处理,当认为网络是可靠时选用该配置
  2. autoheal:各分区协商后重启客户端连接最少的分区节点,恢复集群(CAP 中保证 AP,有状态丢失)
  3. pause_minority:分区发生后判断自己所在分区内节点是否超过集群总节点数一半,如果没有超过则暂停这些节点(保证 CP,总节点数为奇数个)

 

使用 pause_minority 可以有效解决脑裂问题,但是会让集群在出现问题后无法使用

 

RabbitMQ Clustering and Network Partitions -- http://www.rabbitmq.com/partitions.html

高可用方案之脑裂问题探讨(原创) -- http://czmmiao.iteye.com/blog/1180851

RabbitMQ 网络分区问题 -- http://88250.b3log.org/rabbitmq-network-partition

 






技术帖      龙潭书斋      技术分享      rabbitmq      分布式      ha      脑裂问题      network partitions     


京ICP备15018585号