概念
首先,来认识一下什么是集群脑裂,假设我们现在有一个集群,里面有三个节点,一个是master两个data,如下图:
假设现在出现了网络故障,导致一个集群被划分成了两片,两片中的节点无法相互通信,如下图:
如图就出现了两个netword partition, 图中在左边这个network partition里面的data node因为连接不上master node了,可能就会发起一次选举,将自己选举成为master node,如下图:
这样,集群就可能出现了两个master,因为master是集群中的非常重要的角色,主宰了集群状态的维护,以及shard的分配,因此,如果有两个master的话,可能会导致数据被破坏, 这就是集群的脑裂问题
discovery.zen.minimum_master_nodes参数
discovery.zen.minimum_master_nodes
,这个参数对于集群的可靠性来说是非常重要的,同时这个设置也可以预防脑裂问题,也就是一个集群中出现两个master
这个参数的作用,就是告诉ES,直到有足够的master候选节点的时候,才可以选举出一个master,否则就不选举出master.
quorum
这个参数必须被设置为集群中master候选节点的quorum的数量,至于quorum的算法,就是:master候选节点数量 / 2 + 1;
举例说明
假设我们现在有10个节点,都能维护数据,也可以是master候选节点,那么quorum就是 10 / 2 + 1 = 6.
假设现在有三个master节点,还有100个数据节点,那么quorum就是 3 / 2 + 1 = 2.
上面这两个例子都没有问题, 那么再来看一个例子
quorum注意事项
假设现在有两个节点,都是master候选节点,那么quorum就是 2 / 2 + 1 = 2, 此时就会有问题了,因为如果有一个node挂掉后,剩下的这一个master候选节点,是不满足quorum数量的,也就无法选举出新的master节点了,此时整个集群就挂掉了,所以我们只能将参数设置为1, 但是这样的话,就无法阻止脑裂问题的发生了.
来详细看一下,假如两个节点quorum设置为2的情况下,如图
此时,假设这个master节点宕机了,如图:
也就是说,集群中只剩下一个存活的节点了,而我们的quorum设置的是2,那么就不会发起master选举,这个集群也就挂掉了
那么再来看一下两个节点,quorum设置为1的情况. 如图:
假设出现了network partition,如上图中,这两个节点不能相互通信了,此时我们quorum设置为1,就导致data node所在的network partition还有一个master候选节点,他自己还是可以发起选举,然后变成master
如上图,集群中又出现了两个master,导致了脑裂问题
综上所述,一个生产环境的es集群,至少要有3个节点,同时将discovery.zen.minimum_master_nodes
这个参数设置为quorum,也就是2
执行原理
下面来思考一个问题,在三个es节点的集群中,discovery.zen.minimum_master_nodes = 2
的情况下,是如何避免脑裂现象产生的?
假设集群环境如下图:
出现网络分区无非有以下两种情况:
第一种情况,如下图:
master节点被分在了一个network partition,另外两个节点在另一个network partition, 对于上面的现在这个master而言,已经没有足够数量的候选节点连接他了(包括自己在内,必须有两个候选节点)
所以此时,这个master node的master身份会解除掉,尝试重新发起master选举,但是因为master候选节点不够,所以无法发起选举,他就是个data node了
再来看一下下面这个网络分区,两个data node都无法连接master了,而且此时这个网络分区中的master候选节点数量达到了要求,2个,就可以发起选举, 此时,下面这个网络分区中的某一个data node被选举成了master node, 如下:
第二种情况,如下图:
一个master node 和一个data node在一个网络分区内,剩下的一个data node在一个网络分区内.
先看一下左边的这个网络分区, 因为有足够的master候选节点,两个,所以不会对master有任何影响,右边这个网络分区内,这个data node虽然无法连接master,会尝试发起master选举,但是没有足够的master候选节点,所以无法选举成功, 这样就确保说这个不会有两个master的出现
设置方法
说了这么多,那这个参数怎么设置呢
在elasticsearch.yml中配置discovery.zen.minimum_master_nodes: 2
,每一个节点都需要配置.
在我们的es集群中节点是可以动态的增加和下线的,所以quorum可能会随时改变,所以这个参数也可以通过api去随时修改,特别是在节点上线下线的时候,都要做出相应的更改,一旦修改过后,这个配置就会持久化保存下来
api请求如下:1
2
3
4
5
6PUT /_cluster/settings
{
"persistent" : {
"discovery.zen.minimum_master_nodes" : 2
}
}