当前位置: 首页 > news >正文

ES节点故障的容错方案

ES节点故障的容错方案

  • 1. es启动加载逻辑
    • 1.1 segment和translg组成和分析
    • 1.2 es节点启动流程
    • 1.3 es集群的初始化和启动过程
  • 2. master高可用
    • 2.1 选主逻辑
      • 2.1.1 过滤选主的节点列表
      • 2.1.2 Bully算法
      • 2.1.2 类Raft协议
      • 2.1.3 元数据合并
    • 2.2 HA切换
  • 3. 分片高可用
    • 3.1 集群分片汇报
    • 3.2 选举主分片
    • 3.4 主分片恢复
    • 3.4 副分片恢复
    • 3.2 分片恢复的一致性
    • 3.2 HA切换逻辑
    • 3.3 如果写入过程中,分片副本节点宕机,会如何处理?
  • 4. 疑问和思考
    • 4.1 如果一个es宕机,运行在es上的shard数据丢失,是否会自动做均衡?
  • 5. 参考文档

本文主要探讨es集群的高可用容错方案和容错能力的探讨。在出现单机故障时相关的容错方案。

更多关于分布式系统的架构思考请参考文档关于常见分布式组件高可用设计原理的理解和思考


1. es启动加载逻辑

1.1 segment和translg组成和分析

可以参考文章ES高可用架构涉及常用功能整理,本文不再赘述。

1.2 es节点启动流程

在这里插入图片描述
更多细节可以参考玩转Elasticsearch源码-一图看懂ES启动流程

1.3 es集群的初始化和启动过程

es集群的启动大致流程如下
在这里插入图片描述
这里的集群启动过程指集群完全重启时的启动过程,期间要经历选举主节点、主分片、数据恢复等重要阶段,理解其中原理和细节,对于解决或避免集群维护过程中可能遇到的脑裂、无主、恢复慢、丢数据等问题有重要作用。

2. master高可用

2.1 选主逻辑

es的master选主逻辑根据版本不同,有不同的调整

  • 7.0版本之前,使用Bully算法
  • 7.0版本以后,使用类Raft协议,基于Raft协议做了调整

2.1.1 过滤选主的节点列表

选举的第一步,就是需要过滤出选参选的活跃master节点列表,并判断活跃的master列表是否满足选举条件。

  1. 通过参数discovery.zen.ping.unicast.hosts 获取初始的master列表,之后需要做2个事情
  • 通过ping机制,获取列表中活跃的master列表
  • 由于人工静态配置的列表可能不全,因此需要跟活跃的初始列表通信,获取集群中能够成为master的所有节点
  1. 判断过滤出来的活跃master列表数量是否满足discovery.zen.minimum_master_nodes要求,如果不满足,说明集群中参选的数量不足,有可能会有脑裂的风险,不能进一步选举。否则无法满足quorum机制

注: 在7.0后版本中,废除了discovery.zen.minimum_master_nodes参数,而是通过类raft算法自行计算

2.1.2 Bully算法

Bully算法的基本原理就是,根据节点的ID大小来判定谁是leader

Bully算法在选举的时候会发送三种消息类型

  • 选举消息 (Election Message: Sent to announce election.)
  • 应答消息(Answer (Alive) Message: Responds to the Election message.)
  • 选举成功消息 (Coordinator (Victory) Message: Sent by winner of the election to announce victory.)

这三种消息类型组成了Bully的基础消息类型,这也是Bully算法选举必须要了解的东西。

分步解释

  • 节点1向节点,节点3发送选举,并且带上自己的序号1
  • 节点2,3接收到消息之后,进行序号比较,发觉自己的序号更大,向节点1返回应答消息Answer (Alive) Message,告知节点1被踢出选主序列(大概是这个意思)
  • 节点2向节点3发送选举请求,节点3找不到更高序号的节点发送选举请求了节点3向节点2返回应答消息,节点3收不到其他节点的应答消息了
  • 节点3被认为是leader,向其他节点发送Coordinator Message,选举成功的请求,将自己是master节点广播到节点1,节点2

从如上算法的介绍中,可以得知,

  • bully算法有点是简单,能够选出leader很容易。
  • bully算法有很多缺陷,最大的问题还是master假死后不能重新触发选主和难以规避脑裂问题

因此es给bully算增加了限制,以规避bully算法的原生问题。

  • 设置最少得节点参选数量discovery.zen.minimum_master_nodes
  • 至少满足(n+1)/2选票,才能成为leader

这也是为什么在7.0版本,选举算法切换为raft的重要原因。

2.1.2 类Raft协议

raft协议经常接触,可以参考 ETCD高可用架构涉及常用功能整理,不在介绍。

相比于Raft算法,Es的选主算法有如下不同

  • 初始为 Candidate状态
  • 允许多次投票,也就是每个有投票资格的节点可以投多票
  • 候选人可以有投票的机会
  • 可能会产生多个主节点,举例来说,如果node1,node2,node3进行选主

如果node1当选leader,但是node2发来了投票要求,那么node1无条件退出leader状态,node2选为主节点,但是node3也发来了投票要求,那么node2退出leader状态,node3当选主节点。

说明白了,就是保证最后当选的leader为主leader

2.1.3 元数据合并

无论是bully算法还是类raft协议,并不考虑当前节点的数据是否最新,而是在完成选举出leader后进行数据合并中完成数据的一致性问题。

原因是客户端在es的副本写入数据过程中,并不会通知master节点,因此master节点并不知道哪个节点的元数据最新,而是通过后续node节点的数据汇报进行完善,在这一点上跟hdfs的nn类似。

这跟etcd、zk有本质区别,因为etcd、zk的leader节点也是数据节点,所有的数据写入是从leader完成,follower进行同步,因此能够感知谁的数据最新。而es的master节点和node节点是拆分的,因此无法实现这一点,因此只能是类raft协议。

因此在完成leader选举后,需要进行元数据合并

  • 其他的master角色节点(没有选举成为master)发送自身的元数据给master
  • node节点上报自身元数据给master
  • master完成元数据合并后,广播到其他的节点经合并

2.2 HA切换

当探测到节点离开事件时,必须判断当前节点数是否过半。如果达不到半数以上,则放弃Master身份,重新加入集群。如果不这么做,则设想以下情况:假设5台机器组成的集群产生网络分区,2台一组,3台一组,产生分区前,Master位于2台中的一个,此时3台一组的节点会重新并成功选取Master,产生双主,俗称脑裂。(节点失效检测)

在这里插入图片描述

节点失效检测会监控节点是否离线,然后处理其中的异常。失效检测是选主流程之后不可或缺的步骤,不执行失效检测可能会产生脑裂(双主或多主)。

3. 分片高可用

3.1 集群分片汇报

完成master选主后,需要重建集群的shard路由表,该工作全部都是master完成

  • 最开始时,Master不知道主分片在哪,它向集群的所有其他节点询问,让其他节点把[website][0]分片的元信息发过来。
  • Master 收到所有返回后,它就有了这个 shard 的信息,然后根据某种策略选一个分片作为主分片。

是不是效率有些低?这种询问量=shard 数×节点数。所以说我们最好控制shard的总规模别太大。

3.2 选举主分片

构建完所有的分片信息,现在考虑把哪个分片作为主分片。

  • ES 5.x以下的版本,通过对比shard级元信息的版本号来决定。

但是有问题: 在多副本的情况下,考虑到如果只有一个 shard 信息汇报上来,则它一定会被选为主分片,但也许数据不是最新的,版本号比它大的那个shard所在节点还没启动。因此可能会数据丢失。

在解决这个问题的时候,ES 5.x开始实施一种新的策略:给每个 shard 都设置一个 UUID,然后在元信息中记录哪个shard是最新的(ES是先写主分片,再由主分片节点转发请求去写副分片,所以主分片所在节点肯定是最新的,如果它转发失败了,则要求Master删除那个节点,所以可以识别哪个分片最新)

如果集群设置了:禁止分配分片,集群仍会强制分配主分片。

"cluster.routing.allocation.enable": "none"

因此,在设置了上述选项的情况下,集群重启后的状态为Yellow,而非Red。

3.4 主分片恢复

由于每次写操作都会记录事务日志(translog),事务日志中记录了哪种操作,以及相关的数据。因此将最后一次提交(一次提交就是一次 fsync 刷盘的过程)之后的 translog中进行重放,建立索引,如此完成主分片的recovery。

3.4 副分片恢复

副分片的恢复是比较复杂的,在ES的版本迭代中,副分片恢复策略有过不少调整。副分片需要恢复成与主分片一致,同时,恢复期间允许新的索引操作。在目前的6.0版本中,恢复分成两阶段执行:

  • 阶段1
  1. 在主分片所在节点,获取translog保留锁,从获取保留锁开始,会保留translog不受其刷盘清空的影响
  2. 调用接口把shard做快照,这是已经刷磁盘中的分片数据,把这些shard数据复制到副本节点。
  3. 在阶段1完毕前,会向副分片节点发送告知对方启动engine,在阶段2开始之前,副分片就可以正常处理写请求了。

针对当前的分片数据做checkpoint,并送给副分片恢复,耗时长,但是并不影响新的数据写入(写的数据写入到新的translog中,并且在快照期间不会translog不会被清理)

  • 阶段2
  1. translog做快照,这个快照里包含从阶段1开始,到执行translog快照期间的新增索引
  2. 将这些translog发送到副分片所在节点进行重放。

涉及的数据量少,所以耗时短。

由于需要支持恢复期间的新增写操作(让ES的可用性更强),这两个阶段中需要重点关注以下几个问题:

es的分片恢复根据版本不同,有不同的调整

  • 6.0版本之前,副本分片数据全部来自主分片,需要从主分片同步
  • 6.0版本以后,副本分片数据先从本地的translog加载,在从主分片同步,环节主分片压力,是一个分片恢复的提升。

3.2 分片恢复的一致性

恢复时,因为主副分片恢复时间不一致,主分片先进行Recovery,然后副分片才能基于主分片进行Recovery,所以主分片可以工作之后,副分片可能还在恢复中,此时主分片会向副分片发送写请求,因此恢复reply与主分片可能会同时(或者不按发生顺序)对同一个doc进行操作。ES中通过doc的版本号解决这个问题,当收到一个版本号低于doc当前版本号的操作时,会放弃本次操作。对于特定的doc,只有最新一次操作生效。

3.2 HA切换逻辑

当主分片不可用时,es就会重新进行选举,把最新的副本分片提高到主分片的地位,由master进行检测和分片选主,并在分片完成选主后,触发分片的数据恢复逻辑。

3.3 如果写入过程中,分片副本节点宕机,会如何处理?

如果正在写入过程时,副本分片宕机或者出现异常,master会从shard分片中剔除该分片,继续执行写入。

  • 如果分片副本标记写入成功的节点数量,满足要求(具体等待多少副本取决于wait_for_active_shards的配置值),本次写入即可标记成功,并返回给客户端
  • 如果分片副本标记写入成功的节点数量,不满足要求(具体等待多少副本取决于wait_for_active_shards的配置值),本次写入即可标记失败,并返回给客户端,客户端来决定是否重试。

4. 疑问和思考

4.1 如果一个es宕机,运行在es上的shard数据丢失,是否会自动做均衡?

取决于是否配置自动分配参数cluster.routing.allocation.enable,默认是all,表示能够自动触发分配。

  • all:表示能够自动分配分片,如果节点宕机,节点上的涉及的分片副本会自动迁移到其他的节点上,从而满足副本要求(配置了节点标签,不满足分配条件的除外)
  • none: 不触发自动分配,通过在节点主动维护时使用。在进行节点维护时,如果希望临时关闭自动分配,可以使用如下方式
curl -XPUT http://127.0.0.1:9200/_cluster/settings -d '{"transient" : {"cluster.routing.allocation.enable" : "none"}
}'

是否配置主动触发分配,有利有弊,主要原因是自动分配不能识别难以识别业务高峰期,会占用磁盘io和网络带宽。并且如果只是短时间维护节点,触发分配后,机器维护完成,又要重新触发恢复分配,恢复时间较长,因此根据实际情况调整。

个人建议

  • 如果能够清楚的知道节点维护的时间和周期(比如1-2h),可以临时关闭自动分配(恢复时间快)
  • 如果不可预估节点维护的时间或者维护周期过长,不建议关闭自动分配(数据的安全重要度高)

5. 参考文档

  • ElasticSearch——详细看看ES集群的启动流程
  • ElasticSearch-新老选主算法对比

相关文章:

ES节点故障的容错方案

ES节点故障的容错方案 1. es启动加载逻辑1.1 segment和translg组成和分析1.2 es节点启动流程1.3 es集群的初始化和启动过程 2. master高可用2.1 选主逻辑2.1.1 过滤选主的节点列表2.1.2 Bully算法2.1.2 类Raft协议2.1.3 元数据合并 2.2 HA切换 3. 分片高可用3.1 集群分片汇报3.…...

【Flink】FlinkSQL实现数据从Kafka到MySQL

简介 未来Flink通用化,代码可能就会转换为sql进行执行,大数据开发工程师研发Flink会基于各个公司的大数据平台或者通用的大数据平台,去提交FlinkSQL实现任务,学习Flinksql势在必行。 本博客在sql-client中模拟大数据平台的sql编辑器执行FlinkSQL,使用Flink实现数据从Kafka传…...

Unity GC

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com 简略版本 在 Unity 中,垃圾回收(Garbage Collection,GC)采用的是基于标记-清除(Mark and Sweep)算法的自动内存管理机制。 基于标记-清…...

Vue源码系列讲解——变化侦测篇【下】(Array的变化侦测)

目录 1. 前言 2. 在哪里收集依赖 3. 使Array型数据可观测 3.1 思路分析 3.2 数组方法拦截器 3.3 使用拦截器 4. 再谈依赖收集 4.1 把依赖收集到哪里 4.2 如何收集依赖 4.3 如何通知依赖 5. 深度侦测 6. 数组新增元素的侦测 7. 不足之处 8. 总结 1. 前言 上一篇文…...

【机器学习笔记】贝叶斯学习

贝叶斯学习 文章目录 贝叶斯学习1 贝叶斯学习背景2 贝叶斯定理3 最大后验假设MAP(Max A Posterior)4 极大似然假设ML(Maximum Likelihood)5 朴素贝叶斯NB6 最小描述长度MDL 1 贝叶斯学习背景 试图发现两件事情的关系(因果关系,先决条件&结论&#x…...

ElasticSearch之倒排索引

写在前面 本文看下es的倒排索引相关内容。 1:正排索引和倒排索引 正排索引就是通过文档id找文档内容,而倒排索引就是通过文档内容找文档id,如下图: 2:倒排索引原理 假定我们有如下的数据: 为了建立倒…...

win11安装mysql8.3.0压缩包版 240206

mysql社区版安装包版windows安装包下载地址 在系统环境变量path无点.的情况下 powershell 可以 .\ 或 ./ 开头表示当前文件夹cmd 可以直接命令或.\开头, 不能./开头 所以 .\ 在cmd和powershell中通用 步骤 在解压目录 .\mysqld --initialize-insecure root无密码初始化.\m…...

数据库索引与优化:深入了解索引的种类、使用与优化

数据库索引与优化:深入了解索引的种类、使用与优化 索引的种类 数据库索引是提高查询速度的重要手段之一,主要分为以下几种类型: 主键索引(Primary Key Index): 唯一标识表中的每一行数据,保…...

React 错误边界组件 react-error-boundary 源码解析

文章目录 捕获错误 hook创建错误边界组件 Provider定义错误边界组件定义边界组件状态捕捉错误渲染备份组件重置组件通过 useHook 控制边界组件 捕获错误 hook getDerivedStateFromError 返回值会作为组件的 state 用于展示错误时的内容 componentDidCatch 创建错误边界组件 P…...

分享66个相册特效,总有一款适合您

分享66个相册特效,总有一款适合您 66个相册特效下载链接:https://pan.baidu.com/s/1jqctaho4sL_iGSNExhWB6A?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集整理更不…...

chagpt的原理详解

GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的生成式预训练模型。GPT-3是其中的第三代,由OpenAI开发。下面是GPT的基本原理: Transformer架构: GPT基于Transformer架构,该架构由Att…...

dockerfile 详细讲解

当编写 Dockerfile 时,你需要考虑你的应用程序所需的环境和依赖项,并将其描述为一系列指令。下面是一个简单的示例,演示如何编写一个用于部署基于 Node.js 的网站的 Dockerfile: Dockerfile # 使用官方 Node.js 镜像作为基础镜像…...

跟着pink老师前端入门教程-day23

苏宁网首页案例制作 设置视口标签以及引入初始化样式 <meta name"viewport" content"widthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scale1.0"> <link rel"stylesheet" href"css/normaliz…...

JRT监听程序

本次设计避免以往设计缺陷&#xff0c;老的主要为了保持兼容性&#xff0c;在用的设计就不好调了。 首先&#xff0c;接口抽象时候就不在给参数放仪器ID和处理类了&#xff0c;直接放仪器配置实体&#xff0c;接口实现想用什么属性就用什么属性&#xff0c;避免老方式要扩参数时…...

MCU+SFU视频会议一体化,视频监控,指挥调度(AR远程协助)媒体中心解决方案。

视频互动应用已经是政务和协同办公必备系统&#xff0c;早期的分模块&#xff0c;分散的视频应该不能满足业务需要&#xff0c;需要把视频监控&#xff0c;会议&#xff0c;录存一体把视频资源整合起来&#xff0c;根据客户需求&#xff0c;需要能够多方视频互动&#xff0c;直…...

1184. 欧拉回路(欧拉回路,模板题)

活动 - AcWing 给定一张图&#xff0c;请你找出欧拉回路&#xff0c;即在图中找一个环使得每条边都在环上出现恰好一次。 输入格式 第一行包含一个整数 t&#xff0c;t∈{1,2}&#xff0c;如果 t1&#xff0c;表示所给图为无向图&#xff0c;如果 t2&#xff0c;表示所给图为…...

学习 Redis 基础数据结构,不讲虚的。

学习 Redis 基础数据结构&#xff0c;不讲虚的。 一个群友给我发消息&#xff0c;“该学的都学了&#xff0c;怎么就找不到心意的工作&#xff0c;太难了”。 很多在近期找过工作的同学一定都知道了&#xff0c;背诵八股文已经不是找工作的绝对王牌。企业最终要的是可以创造价…...

Android 11 webview webrtc无法使用问题

问题&#xff1a;Android 11 webview 调用webrtc无法使用, 看logcat日志会报如下错误 [ERROR:address_tracker_linux.cc(245)] Could not send NETLINK request: Permission denied (13) 查了下相关的网络权限都有配置了还是不行&#xff0c;还是报这个权限问题 原因&#xff1…...

嵌入式单片机中晶振的工作原理

晶振在单片机中是必不可少的元器件&#xff0c;只要用到CPU的地方就必定有晶振的存在&#xff0c;那么晶振是如何工作的呢&#xff1f; 什么是晶振 晶振一般指晶体振荡器&#xff0c;晶体振荡器是指从一块石英晶体上按一定方位角切下的薄片&#xff0c;简称为晶片。 石英晶体谐…...

AWS配置内网EC2服务器上网【图形化配置】

第一种方法&#xff1a;创建EC2选择启用分配公网ip 1. 创建vpc 2. 创建子网 3. 创建互联网网关 创建互联网网关 创建互联网网关 &#xff0c;设置名称即可 然后给网关附加到新建的vpc即可 4. 给新建子网添加路由规则&#xff0c;添加新建的互联网网关然后点击保存更改 5. 新建…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...