集群为了保证数据一致性,在同步数据的同时也会通过节点之间的心跳通信来保证对方存活。那如果集群节点通信异常会发生什么,系统如何保障正常提供服务,使用何种策略回复呢?

rabbitmq提供的处理脑裂的方法有两种:autoheal、pause_minority.

autoheal指的是在出现脑裂且恢复时采用分区中与客户端连接数最多的一个分区来作为winner,并将所有的losers分区重启。

pause_miniroty指的是在出现脑裂后判断自己是否为众数者majority,即自己所在分区是否为总节点数的一半以上length(AliveNodes) / length(Nodes) > 0.5,如果属于众数者则正常工作,否则做rabbit:stop()操作,并以1秒周期查询自己是否属于众数者。

下面主要介绍下autoheal的实现原理。

首先在rabbit.erl中根据启动流程中可以看到

-rabbit_boot_step({rabbit_node_monitor,
[{description, "node monitor"},
{mfa, {rabbit_sup, start_restartable_child,
[rabbit_node_monitor]}},
{requires, [rabbit_alarm, guid_generator]},
{enables, core_initialized}]}).

启动并注册系统事件来获取(rabbit_node_monitor.erl)

 {ok, _} = mnesia:subscribe(system),

当环境中出现分区恢复后,mneisa会收到{nodeup, Node},并根据此节点来获取远端有记录mnesia down过的节点,当两个节点都认为对方出现过down的情况下,即会发送{inconsistent_database, Context, Node}系统事件【1】,并在所有节点都起来的情况下开始autoheal, rabbit_node_monitor.erl。

handle_info({mnesia_system_event,
{inconsistent_database, running_partitioned_network, Node}},
State = #state{partitions = Partitions,
monitors = Monitors}) ->
%% We will not get a node_up from this node - yet we should treat it as
%% up (mostly).
State1 = case pmon:is_monitored({rabbit, Node}, Monitors) of
true -> State;
false -> State#state{
monitors = pmon:monitor({rabbit, Node}, Monitors)}
end,
ok = handle_live_rabbit(Node),
Partitions1 = lists:usort([Node | Partitions]),
{noreply, maybe_autoheal(State1#state{partitions = Partitions1})};
maybe_autoheal(State = #state{autoheal = AState}) ->
case all_nodes_up() of
true -> State#state{autoheal = rabbit_autoheal:maybe_start(AState)};
false -> State
end.

利用autoheal处理脑裂的时候,先在节点中找到一个leader,然后这个leader来公正地决定胜负。

maybe_start(not_healing) ->
case enabled() of
true -> Leader = leader(),
send(Leader, {request_start, node()}),
rabbit_log:info("Autoheal request sent to ~p~n", [Leader]),
not_healing;
false -> not_healing
end;

针对获取到的所有分区开始做决定以选择分区中的winner和losers,决策原则是根据各个分区中所拥有的连接数的个数来确定的,如果连接数相同,则选择分区内节点最多的分区。

make_decision(AllPartitions) ->
Sorted = lists:sort([{partition_value(P), P} || P <- AllPartitions]),
[[Winner | _] | Rest] = lists:reverse([P || {_, P} <- Sorted]),
{Winner, lists:append(Rest)}. partition_value(Partition) ->
Connections = [Res || Node <- Partition,
Res <- [rpc:call(Node, rabbit_networking,
connections_local, [])],
is_list(Res)],
{length(lists:append(Connections)), length(Partition)}.

之后loser会做重启,可能会因此而导致数据丢失。

参考文献

1. mnesia之inconsistent_database. http://my.oschina.net/hncscwc/blog/174416

2. rabbitmq对network partition的处理. http://my.oschina.net/hncscwc/blog/174417

rabbitmq之partitions的更多相关文章

  1. RabbitMQ Network Partitions的预警和处理策略

    网络分区的意义 RabbitMQ的模型类似交换机模型,且采用erlang这种电信网络方面的专用语言实现.RabbitMQ集群是不能跨LAN部署(如果要WAN部署需要采用专门的插件)的,也就是基于网络情 ...

  2. RabbitMQ Network Partitions

    Clustering and Network Partitions RabbitMQ clusters do not tolerate network partitions well. If you ...

  3. RabbitMQ Network Partitions 处理策略

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 网络分区的意义 RabbitMQ的模型 ...

  4. RabbitMQ配置文件

    配置文件Config 在Web的可视化管理界面中可以看到一些文件的路径 比如 Config文件的地址 数据库存放的文件夹 log文件的地址 进入到这个文件夹会发现有这些文件,其中example是con ...

  5. rabbitmq.config配置文件

    %% -*- mode: erlang -*-%% -------------------------------------------------------------------------- ...

  6. RabbitMQ 集群与网络分区(理论知识)

    关于network partition网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若两个子网间的交换机故障了即发 ...

  7. 【rabbitmq】RabbitMQ 集群与网络分区

    网络分区(network partitions) 官网-网络分区 网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若 ...

  8. RabbitMQ脑裂问题解决方案调查

    现象: RabbitMQ GUI上显示 Network partition detectedMnesia reports that this RabbitMQ cluster has experien ...

  9. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

随机推荐

  1. 转载:回编译APK出错:java.nio.char set.MalformedInputException: Input length = 1

    使用APKtool回编译APK,出现错误如下:    Exception in thread "main" org.yaml.snakeyaml.error.YAMLExcepti ...

  2. HDU5727 Necklace(枚举 + 二分图最大匹配)

    题目大概说有n个yang珠子n个yin珠子,要交替串成一个环形项链,有些yang珠子和某个yin珠子相邻这个yang珠子会不高兴,问最少有几个yang珠子不高兴. 自然会想到直接用状压DP去解,转移很 ...

  3. bzoj1008 [HNOI2008]越狱

    1008: [HNOI2008]越狱 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5099  Solved: 2207 Description 监狱有 ...

  4. Extjs用到的一些有用的网页的集锦

    1. extJS常用的4中Ajax异步提交 http://www.2cto.com/kf/201403/284083.html http://blog.csdn.net/goodshot/articl ...

  5. [Leetcode] Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  6. 【POJ】3071 Football

    http://poj.org/problem?id=3071 题意:2^n支队伍进行淘汰赛,每一轮都是第一个与第二个,第三个与第四个比赛,给出了这些人之间的胜率,赢了的进入下一轮,相对位置不变.一共n ...

  7. 去掉inline-block元素默认间距的几种方法

    方法1:使用负margin值一般是-3px,部分浏览器可能不同,不太推荐使用. 方法2:去掉多余空格将元素紧挨着写去掉多余空格,但降低了可读性. 方法3:使用font-size:0在外层父元素加上fo ...

  8. storyboard自动布局时,代码修改 constraint 的值,没有反应

    从 width equalto 其他控件的 width   到  当前控件固定的 width, 再到不固定当前控件的 width, 只固定当前控件的 trailing 是一个不错的思想.

  9. Maven Repository

    The usefully link for Maven Reponsitory display as below: http://mvnrepository.com/ For example, To ...

  10. js的小效果-图片放大镜效果

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...