欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

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

时间:2023-04-15
前言 什么是脑裂问题

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:-UseCMSInitiatingOccupancyonly14-:-XX:+UseG1GC

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

node.master: truenode.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、数据库、架构设计、面试题、电子书等,期待你的关注!

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。