Elasticsearch高可用之集群脑裂问题详解

前言

什么是脑裂问题

ES在主节点上产生分歧,产生多个主节点,从而使集群分裂,使得集群处于异常状态。这个现象叫做脑裂。脑裂问题其实就是同一个集群的不同节点对于整个集群的状态有不同的理解,导致操作错乱,类似于精神分裂

举个栗子:

下图是一个有两个节点的elasticsearch集群。集群维护一个单个索引并有一个分片和一个复制节点。节点1在启动时被选举为主节点并保存主分片(在下面的schema里标记为0P),而节点2保存复制分片(0R

这时如果在两个节点之间的通讯中断了(网络问题或只是因为其中一个节点无响应(例如stop-the-world垃圾回收,es进程被占用,内存溢出等))

此时,两个节点都会觉得对方挂了。

对于节点1来说,他自己就是master,所以不需要做什么

对于节点2,因为此时集群就只有他一个节点,当他选举一个节点当master,那就只会是他自己。在elasticsearch集群,是由主节点来决定将分片平均的分布到节点上的。节点2保存的是复制分片,但它相信主节点不可用了。所以它会自动提升复制节点为主节点。

那么此时,整个es集群就会出现两个master,打在节点1上的索引请求会将索引数据分配在主节点,同时打在节点2的请求会将索引数据放在分片上。

也就是说,如果数据添加到es集群,就会出现分散到两个分片中,分片的两份数据分开了,不做一个全量的重索引很难对它们进行重排序。查询集群数据的请求都会成功完成,但是请求返回的结果是不同的。访问不同的节点,会发现集群状态不一样,可用节点数不一样,而且结果数据也会不一样

解决思路

脑裂主要是在master节点挂掉或子节点联系不上master时出现,那么我们就要尽可能保证不会出现节点挂掉的情况

1、网络问题

保证网络稳定,及时预警,重启集群

2、master节点负载过大

避免master节点因为工作负载过大出现响应中断从而引发脑裂

可以在jvm.options中增加堆内存大小或者修改合适的GC处理器

-Xms4g

-Xmx4g

## G1GC Configuration

# to use G1GC, uncomment the next two lines and update the version on the

# following three lines to your version of the JDK

# 8-13:-XX:-UseConcMarkSweepGC

# 8-13:-XX:-UseCMSInitiatingOccupancyOnly

14-:-XX:+UseG1GC

也可以对集群的节点做读写分离,master节点专门做集群master管理,master节点配置

node.master: true

node.data: false

同时设置一批data节点负责存储数据和处理请求

node.master: false 

node.data: true

如果确实还是顶不住,那么就可以再设置一批client节点只负责处理用户请求,实现请求转发,负载均衡等功能,让data节点只负责存储数据

node.master: false  

node.data: false

3、优化方法方面

由于elasticsearch6.X和elasticsearch7.X配置出入较大,所以这部分的优化分为两种

elasticsearch6.X:

discovery.zen.ping.multicast.enabled: falsediscovery.zen.ping.unicast.hosts: ["master1", "master2", "master3"]discovery.zen.ping_timeout:5discovery.zen.minimum_master_nodes:2

discoveryzen.ping.multicast.enabled

将data节点的默认的master发现方式由multicast(多播)修改为unicast(单播),使新加入的节点快速确定master位置

discovery.zen.ping.unicast.hosts

提供其他 Elasticsearch 服务节点的单点广播发现功能。配置集群中基于主机 TCP 端口的其他 Elasticsearch 服务列表

discovery.zen.ping_timeout

节点等待响应的时间,默认值是3秒,增加这个值,会增加节点等待响应的时间,从一定程度上会减少误判

discovery.zen.minimum_master_nodes

一个节点需要看到的具有master节点资格的最小数量,然后才能在集群中做操作。官方的推荐值是(N/2)+1,其中N是具有master资格的节点的数量,设置这个参数后,只有足够的master候选节点时,才可以选举出一个master

elasticsearch7.X:

官网文档中有这么一段话

If the cluster is running with a completely default configuration then it will automatically bootstrap a cluster based on the nodes that could be discovered to be running on the same host within a short time after startup. This means that by default it is possible to start up several nodes on a single machine and have them automatically form a cluster which is very useful for development environments and experimentation. However, since nodes may not always successfully discover each other quickly enough this automatic bootstrapping cannot be relied up

译:如果集群以完全默认的配置运行,那么它将在启动后的短时间内根据可以发现在同一主机上运行的节点自动引导集群。这意味着默认情况下,可以在一台机器上启动多个节点并让它们自动形成一个集群,这对于开发环境和实验非常有用。但是,由于节点可能并不总是足够快地成功发现彼此,因此不能依赖这种自动引导,也不能在生产部署中使用。

所以需要配置如下参数,让集群内的节点更快的互相发现

cluster.initial_master_nodes: ["node-1", "node-2"]discovery.seed_hosts: ["host1", "host2"]

discovery.seed_hosts

在没有任何网络配置的情况下,Elasticsearch将直接绑定到可用的环回地址,并扫描本地端口9300到9305,以连接到同一服务器上运行的其他节点,集群中的节点能够发现彼此并选择一个主节点

cluster.initial_master_nodes

使用一组初始的符合主条件的节点引导集群  

脑裂修复

当elasticsearch集群重新选举出一个master节点时,由于之前索引的两份拷贝已经不一样了,elasticsearch会认为选出来的master保留的分片是“主拷贝”并将这份拷贝推送给集群中的其他节点。

这种情况就很容易导致正确的节点上的数据被选举出来的master节点的错误数据覆盖掉,造成数据丢失。

所以需要

1、给所有数据重新索引

POST _reindex{  "source": {    "index": "twitter"  },  "dest": {    "index": "new_twitter",    "op_type": "create"  }}

2、逐个关闭节点并备份数据,分析比对数据是否是最新的。如果是保存的数据是最新的,启动它并且让它被选为主节点。然后就可以启动集群的其他节点了

最后

脑裂问题很难被彻底解决。在elasticsearch的问题列表里仍然有关于这个的问题, 描述了在一个极端情况下正确设置了minimum_master_nodes的参数时仍然产生了脑裂问题。elasticsearch项目组正在致力于开发一个选主算法的更好的实现,但如果你已经在运行elasticsearch集群了那么你需要知道这个潜在的问题。

欢迎关注我的微信公众号:Java架构师进阶编程 

专注分享Java技术干货,包括JVM、SpringBoot、SpringCloud、数据库、架构设计、面试题、电子书等,期待你的关注!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方木丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值