01

什么是脑裂?

要了解什么是脑裂,首先我们要明白es集群的组成。ES集群由一个主节点(多个备选节点组成)和多个数据节点组成的,主节点负责创建,删除索引,分配分片,追踪集群的节点状态等工作,即是调度节点,计算压力比较低,而数据节点负责数据存储与具体的操作,比如搜索,聚合等任务,计算压力比较大。

在正常情况下,当主节点无法工作时,会从备选节点中选举出一个节点,变为新的主节点,原主节点回归后变成备选节点。但是有时候,由于网络抖动等种种原因,主节点没有及时响应,集群错误的认为主节点已经下线了,然后选举出了新的节点,此时集群中就有了两个主节点,其他数据节点不知道听从谁的调度,这时候就产生了脑裂问题。

02

脑裂产生的原因

那么脑裂到底是怎么产生的呢,其实主要分为以下三个方面:

1.网络抖动

内网一般不会出现该问题,可以监控内网状态。外网的网络出现问题的可能性大些。

2.节点负载:

如果主节点同时承担了数据节点的工作,可能会因为工作量过大导致对应的实例停止响应,从而导致其他节点认为主节点挂掉了,然后选择新的主节点。

3.内存回收:

大规模的回收内存也会导致ES集群失去响应。

03

脑裂问题解决

既然我们知道了脑裂问题产生的原因,那么我们就可以根据原因去解决:

1.不要把主节点设置位数据节点,即node.master和node.data不要同时设置为true

//主节点配置:node.master: truenode.data: false

从节点配置:node.master: falsenode.data: true

2.将节点响应超时discovery.zen.ping_timeout稍稍设置长一些(默认是3秒)。默认情况下, 一个节点会认为, 如果master节点在 3 秒之内没有应答, 那么这个节点就是挂掉了, 而增加这个值, 会增加节点等待响应的时间, 从一定程度上会减少误判。

3.discovery.zen.minimum_master_nodes的默认值是1,当具备成为主节点的从节点的个数满足这个数字且都认为主节点挂了则会进行选举产生新的主节点。我们可以适当的把这个值改大,减少出现脑裂的概率,官方给出的建议是(n/2)+1,n为有资格成为主节点的节点数node.master=true。

04

总结

以上的解决方法只能减缓这种现象的发生,并没有从根本上去杜绝。

那么如果发生了脑裂,如何解决呢?

  1. 给所有的数据重建索引

  2. 如果脑裂产生了,那么就要十分小心的重启集群,停掉所有的节点并决定哪一个节点第一个启动,如果需要,单独启动每一个节点分析它保存的数据,如果部署有效的,关掉它,并删除它数据目录的内容。如果你招到了你想要保存数据的系欸但,启动它并检查日志确保它被选为主节点,这之后你就可以安全的启动你的集群中的其他节点了。