ES脑裂问题

ES脑裂问题

概述

一个正常es集群中只有一个主节点,主节点负责管理整个集群,集群的所有节点都会选择同一个节点作为主节点所以无论访问那个节点都可以查看集群的状态信息。而脑裂问题的出现就是因为从节点在选择主节点上出现分歧导致一个集群出现多个主节点从而使集群分裂,使得集群处于异常状态。

原因

1、网络原因

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

2、节点负载

主节点即负责管理集群又要存储数据,当访问量大时可能会导致ES实例反应不过来而停止响应,此时其他节点在向主节点发送消息时得不到主节点的响应就会认为主节点挂了,从而重新选择主节点。

3、回收内存

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

所以内网负载的可能性大,外网网络的可能性大。

主节点选举机制

再来看看ES的主动选举机制:

ES集群一旦建立起来以后,会选举出一个master,其他都为slave节点。但是具体操作的时候,每个节点都提供写和读的操作。就是说,你不论往哪个节点中做写操作,这个数据也会分配到集群上的所有节点中。这里有某个节点挂掉的情况,如果是slave节点挂掉了,那么首先关心数据会不会丢呢?不会。如果你开启了replica,那么这个数据一定在别的机器上是有备份的。别的节点上的备份分片会自动升格为这份分片数据的主分片。这里要注意的是这里会有一小段时间的yellow状态时间。如果是主节点挂掉怎么办呢?当从节点们发现和主节点连接不上了,那么他们会自己决定再选举出一个节点为主节点。但是这里有个脑裂的问题,假设有5台机器,3台在一个机房,2台在另一个机房,当两个机房之间的联系断了之后,每个机房的节点会自己聚会,推举出一个主节点。这个时候就有两个主节点存在了,当机房之间的联系恢复了之后,这个时候就会出现数据冲突了。

预防方案

1、角色分离

在es集群中配置2到3个主节点并且让它们只负责管理不负责存储,从节点只负责存储。另外从节点禁用自动发现机制并为其指定主节点。在elasticsearch.yml文件中,
主节点:

node.master=true
node.data=false

从节点:

node.master=false
node.data=ture
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]

2、参数配置

discovery.zen.ping_timeout: 3

此参数指定从节点访问主节点后如果3秒之内没有回复则默认主节点挂了,我们可以适当的把它改大,这样可以减少出现脑裂的概率。

discovery.zen.minimum_master_nodes: 2

该参数的意思是,当具备成为主节点的从节点的个数满足这个数字且都认为主节点挂了则会进行选举产生新的主节点。例如,ES集群有三个从节点有资格成为主节点,这时这三个节点都认为主节点挂了则会进行选举,此时如果这个参数的值是4则不会进行选举。我们可以适当的把这个值改大,减少出现脑裂的概率,官方给出的建议是(n/2)+1,n为有资格成为主节点的节点数(node.master=true)。

这里有几个例子:

  • 如果你有 10 个节点(能保存数据,同时能成为 master),法定数就是 6 。
  • 如果你有 3 个候选 master 节点,和 100 个 data 节点,法定数就是 2 ,你只要数数那些可以做master 的节点数就可以了。
  • 如果你有两个节点,你遇到难题了。法定数当然是 2 ,但是这意味着如果有一个节点挂掉,你整个集群就不可用了。 设置成 1 可以保证集群的功能,但是就无法保证集群脑裂了,像这样的情况,你最好至少保证有 3 个节点。

由于ELasticsearch是动态的,你可以很容易的添加和删除节点,但是这会改变这个法定个数。你不得不修改每一个索引节点的配置并且重启你的整个集群只是为了让配置生效,这将是非常痛苦的一件事情。

基于这个原因,discovery.zen.minimum_master_nodes(还有一些其它配置)允许通过 API 调用的方式动态进行配置。当集群在线运行的时候,可以这样修改配置:

PUT /_cluster/settings
{
    "persistent" : {
        "discovery.zen.minimum_master_nodes" : 2
    }
}

这将成为一个永久的配置,并且无论你配置项里配置的如何,这个将优先生效。当你添加和删除 master 节点的时候,你需要更改这个配置。

你可能感兴趣的:(ES脑裂问题)