rabbitmq之partitions
集群为了保证数据一致性,在同步数据的同时也会通过节点之间的心跳通信来保证对方存活。那如果集群节点通信异常会发生什么,系统如何保障正常提供服务,使用何种策略回复呢?
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的更多相关文章
- RabbitMQ Network Partitions的预警和处理策略
网络分区的意义 RabbitMQ的模型类似交换机模型,且采用erlang这种电信网络方面的专用语言实现.RabbitMQ集群是不能跨LAN部署(如果要WAN部署需要采用专门的插件)的,也就是基于网络情 ...
- RabbitMQ Network Partitions
Clustering and Network Partitions RabbitMQ clusters do not tolerate network partitions well. If you ...
- RabbitMQ Network Partitions 处理策略
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 网络分区的意义 RabbitMQ的模型 ...
- RabbitMQ配置文件
配置文件Config 在Web的可视化管理界面中可以看到一些文件的路径 比如 Config文件的地址 数据库存放的文件夹 log文件的地址 进入到这个文件夹会发现有这些文件,其中example是con ...
- rabbitmq.config配置文件
%% -*- mode: erlang -*-%% -------------------------------------------------------------------------- ...
- RabbitMQ 集群与网络分区(理论知识)
关于network partition网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若两个子网间的交换机故障了即发 ...
- 【rabbitmq】RabbitMQ 集群与网络分区
网络分区(network partitions) 官网-网络分区 网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若 ...
- RabbitMQ脑裂问题解决方案调查
现象: RabbitMQ GUI上显示 Network partition detectedMnesia reports that this RabbitMQ cluster has experien ...
- Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践
目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ? RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...
随机推荐
- 2017亚洲VR&AR博览会暨高峰论坛
2017亚洲VR&AR博览会暨高峰论坛 2017 Asia VR&AR Fair & Summit(VR&AR Fair 2017) 活动介绍活动时间: 2017年3月 ...
- BZOJ 2957 & 线段树上的查询
题意: 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个二 ...
- 解决JS浮点数(小数)计算加减乘除的BUG
在JavaScript中输出下面这些数值(注意不能作为字符串输出):0.1000000000000000000000000001(28位小数).0.10000000000000000000000000 ...
- STL 的运用 istringstream的运用
单词数 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- BZOJ3226[Sdoi2008]校门外的区间 题解
题目大意: 有5种运算维护集合S(S初始为空)并最终输出S. 5种运算如下: U T S∪T I T S∩T D T S-T C T T-S S T S⊕T 基本集合运算如下: A∪B {x : ...
- Android 魅族等SmartBar适配
通过反射获取是否含有SmartBar: /** * 判断是否有SmartBar */ private boolean hasSmartBar() { // SP存储是否显示SmartBar if (! ...
- 【BZOJ】2693: jzptab
http://www.lydsy.com/JudgeOnline/problem.php?id=2693 题意:求$\sum_{i=1}^{n} \sum_{j=1}^{m} lcm(i, j)$, ...
- 初识socket
socket也叫套接字,用于通信的一个句柄,描述IP与端口信息,程序通过套接字可以向网络发出请求或者应答网络请求. socket起源与unix,而unix/Linux基本哲学之一就是”一切皆文件“,对 ...
- 优化MySchool总结习题
1) 在SQL Server 中,为数据库表建立索引能够( C ). A. 防止非法的删除操作 B. 防止非法的插入操作 C. 提高查询性能 D. 节约数据库的磁盘空间 解析:索引的作用是通过使用索引 ...
- java实现MD5加密
mport java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Creat ...