【笔记】Elasticsearch脑裂问题

时间:2021-01-17 14:46:08

1.定义

由于某些节点的失效,部分节点的网络连接会断开,并形成一个或多个与原集群一样名字的小集群,这种情况称为集群脑裂(split-brain)现象,分裂的不同小集群会选出各自的master节点,使这些master节点同时拥有索引和修改集群数据的权利。

2.形成原因

①:网络原因
内网一般不会出现这个问题,可以监控内网流量状态。外网的网络出现问题的可能性大些。

②:节点负载
由于master节点与data节点都是混合在一起的,所以当工作节点的负载较大(确实也较大)时,导致对应的ES实例停止响应,而这台服务器如果正充当着master节点的身份,那么一部分节点就会认为这个master节点失效了,故重新选举新的节点,这时就出现了脑裂;

③:回收内存
由于data节点上ES进程占用的内存较大,较大规模的内存回收操作也能造成ES进程失去响应。

3.解决办法

①:推测出原因应该是由于节点负载导致了master进程停止响应,继而导致了部分节点对于master的选择出现了分歧。为此,一个直观的解决方案便是将master节点与data节点分离。添加三台服务器进入ES集群,不过它们的角色只是master节点,不担任存储和搜索的角色,故它们是相对轻量级的进程。可以通过以下配置来限制其角色:
node.master: true
node.data: false

当然,其它的节点就不能再担任master了,把上面的配置反过来即可。这样就做到了将master节点与data节点分离。

当然,为了使新加入的节点快速确定master位置,可以将data节点的默认的master发现方式有multicast修改为unicast:

discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: [“master1”, “master2”, “master3”]

elasticsearch的集群是内嵌自动发现功能的。

elasticsearch的集群是内嵌自动发现功能的。只需要在每个节点配置好了集群名称,节点名称,互相通信的节点会根据es自定义的服务发现协议去按照多播的方式来寻找网络上配置在同样集群内的节点。
和其他的服务发现功能一样,es是支持多播和单播的。

多播是需要看服务器是否支持的,由于其安全性,其实现在基本的云服务(比如阿里云)是不支持多播的,所以即使开启了多播模式,也仅仅只能找到本机上的节点。

单播模式安全,也高效,但是缺点就是如果增加了一个新的机器的话,就需要每个节点上进行配置才生效了。

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

③:discovery.zen.minimum_master_nodes(默认是1):这个参数控制的是,一个节点需要看到的具有master节点资格的最小数量,然后才能在集群中做操作。官方的推荐值是(N/2)+1(向下取整),其中N是具有master资格的节点的数量(我的情况是3,因此这个参数设置为2,但对于只有2个节点的情况,设置为2就有些问题了,一个节点DOWN掉后,肯定连不上2台服务器了,这点需要注意)。