一、概述
一个正常ElasticSearch集群中只有一个主节点,主节点负责管理整个集群,集群的所有节点都会选择同一个节点作为主节点,所以无论访问那个节点都可以查看集群的状态信息。 而脑裂问题的出现就是因为从节点在选择主节点上意见不一致,出现分歧导致一个集群出现多个主节点从而使集群分裂,使得集群处于异常状态
二、产生原因
- 网络原因。
集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片 - 节点负载
主节点即负责管理集群又要存储数据,当访问量大时可能会导致es实例反应不过来而停止响应,此时其他节点在向主节点发送消息时得不到主节点的响应就会认为主节点挂了,从而重新选择主节点。 - 内存回收:data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。
ElasticSearch集群一旦建立起来以后,会选举出一个master,其他都为slave节点。但是具体操作的时候,每个节点都提供写和读的操作。就是说,你不论往哪个节点中做写操作,这个数据也会分配到集群上的所有节点中。
这里有某个节点挂掉的情况,如果是slave节点挂掉了,那么首先关心,数据会不会丢呢?不会。如果你开启了replicate副本,那么这个数据一定在别的机器上是有备份的。别的节点上的备份分片会自动升格为这份分片数据的主分片。这里要注意的是这里会有一小段时间的yellow状态时间。
如果主节点挂掉怎么办?当从节点们发现和主节点连接不上了,那么他们会自己决定再选举出一个节点为主节点。这个时候就可能会产生脑裂问题,假设有5台机器,3台在一个机房,2台在另一个机房,当两个机房之间的联系断了之后,每个机房的节点会自己聚会,推举出一个主节点。这个时候就有两个主节点存在了,当机房之间的联系恢复了之后,这个时候就会出现数据冲突了。
三、解决方案
- 角色分离
集群中配置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:1
该参数的意思是,当具备成为主节点的从节点的个数满足这个数字且都认为主节点挂了则会进行选举产生新的主节点
例如:es集群有三个从节点有资格成为主节点,这时这三个节点都认为主节点挂了则会进行选举,此时如果这个参数的值是4则不会进行选举。
我们可以适当的把这个值改大,减少出现脑裂的概率,官方给出的建议是(n/2)+1,n为有资格成为主节点的节点数node.master=true
当然,可以通过增加物理机的方式来解决这个问题