Elasticsearch 主副分片切换过程中对业务写入有影响吗

🍊🍉🍋 先说下结论,只要集群中的工作节点过半,有候选的master节点,挂掉的节点中不同时包含索引的主分片和副分片,那么ES是可以做到让业务无感知的进行主副分片切换的。

蓝胖子会先讲解下ES集群写入文档的原理,并对异常情况进行分析,最后来模拟集群写入过程中节点宕机的情况来对这个问题展开讨论。

主副分片的写入流程

之前我在Elasticsearch 如何保证写入过程中不丢失数据的 有提到ES 通过translog 保证了segment在写入完成后即使会在内存停留一段时间也不会因为宕机而丢失数据。但是没有提到ES在写入时,副本和主节点之间的关系,现在把这部分补充完整。

如下图所示,有3个es节点,es03是整个集群的master节点,同时也承担数据节点的角色,es01,es02都是数据节点,同时也可以成为master节点候选者。

image.png

es client客户端发送插入文档的请求,默认是随机选取集群中的一个节点进行发送,假设请求发送给了es02,由于插入和修改操作只能由主分片进行,此时主分片又是es03节点,所以es02这个时候就充当了协调节点的角色,对客户端的请求进行了转发,转发给了es03

正常情况下es03 会在主分片对数据进行写入,写入成功后,再将插入请求转发到副本节点进行复制,等待副本节点回应后(无论成功还是失败都会回应)会将此次写入数据的结果返回给协调节点es03,es03再将结果返回给客户端。

分片写入过程中的异常处理流程

上面是一个正常的流程,现在来看一下一个异常的情况,如下图所示,在协调节点es02转发请求给es03时,es03 在处理分片写入过程中宕机了,这个时候,客户端的此次写入会失败掉吗?

image.png

es03 节点上的是主分片,这里有必要对es03节点宕机的时机进行分析,

1,es03节点在主分片写入前宕机。

2,es03 节点在主分片写入成功后,还没来得及向副分片写入数据就宕机。

3,es03节点在副分片也写入成功后,就宕机。

以上是主分片的3种宕机的情况。

接着,回到写入流程上,es03节点宕机了,es02的http 转发请求将会失败,此时es02节点在收到失败后,将会进行重试,并且由于此时是主分片,且是master节点宕机,所以,es02节点会等待整个集群重新选出主分片和主节点后,再会进行重试

📢📢📢需要注意的是,如果es03节点宕机的时机是主分片写入前,或者是还没来得及向副分片进行复制就宕机,那么重试不会有任何问题,新的主分片将会拥有写入失败的数据。如下图所示,

image.png

如果es03节点在宕机前已经完成了副分片的复制,es01节点已经拥有了这条插入的数据,那么协调节点es02的重试会导致多插入一条数据吗?

其实是不会的,在Es节点内部,每个文档都会有一个_idversion_id 标记唯一一个文档,version 用于版本更新,ES的更新是基于乐观锁机制,并发更新时有可能返回致版本错误,需要业务方进行重试,更新成功后文档的version字段会进行加1。

在协调节点转发插入请求前,便会生成_idversion 字段,所以如果es03节点已经将插入的数据复制到了副分片,那么es02节点在进行重试发请求时,请求到达es01节点,会在文档中发现相同的_idversion的文档,则会认为数据已经插入了,忽略掉这次重试的插入请求。ES集群会正常的进行插入数据,后续客户端的插入请求都将被转发到es01节点的主分片进行插入。客户端除了直接请求es03节点,不会察觉到es03节点挂了。

上面是在文档写入过程中节点宕机的情况,除以以外,如果es03节点如果没有在处理请求就宕机了,那么集群会重新选主节点和主分片,如果选举过程还没结束,此时客户端就发送来插入请求,那么会等待选举结束后,es02才会继续转发请求到新主分片节点。

所以,你可以看到,Es节点可以通过重试和等待主分片选举实现让业务无感知的进行主副分片的切换。

压测集群模拟节点宕机

下面我用docker compose 启动一个3节点集群,然后对集群进行并发插入,接着模拟节点 宕机,主动kill掉一个节点,来看看最后插入的数据是否和并发插入数据是吻合的,并且插入过程没有报错。

启动一个es集群,

version: '2.2'  
services:  es01:  image: docker.elastic.co/elasticsearch/elasticsearch:7.14.2  container_name: es01  environment:  - node.name=es01  - cluster.name=es-docker-cluster  - discovery.seed_hosts=es02,es03  - cluster.initial_master_nodes=es01,es02,es03  - bootstrap.memory_lock=true  - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  ulimits:  memlock:  soft: -1  hard: -1  ports:  - 9200:9200  es02:  image: docker.elastic.co/elasticsearch/elasticsearch:7.14.2  container_name: es02  environment:  - node.name=es02  - cluster.name=es-docker-cluster  - discovery.seed_hosts=es01,es03  - cluster.initial_master_nodes=es01,es02,es03  - bootstrap.memory_lock=true  - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  ulimits:  memlock:  soft: -1  hard: -1  ports:  - 9201:9200  es03:  image: docker.elastic.co/elasticsearch/elasticsearch:7.14.2  container_name: es03  environment:  - node.name=es03  - cluster.name=es-docker-cluster  - discovery.seed_hosts=es01,es02  - cluster.initial_master_nodes=es01,es02,es03  - bootstrap.memory_lock=true  - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  ulimits:  memlock:  soft: -1  hard: -1  ports:  - 9202:9200

启动之后,创建了一个名字叫做cd的索引,

PUT /cd
{"mappings": {"properties": {"info":{"type": "text"},"age":{"type":"integer"},"email":{"type": "keyword","index": false},"name":{"type": "object","properties": {"firstName": {"type": "keyword"},"lastName": {"type": "keyword"}}}}}  
}

通过kibana进行查看,目前的主节点es03

Pasted image 20240315181819.png

接着,我用golang写了一个程序总共发出10万的插入请求,100并发进行发出,代码如下,

package main  import (  "fmt"  "github.com/google/uuid"   "io/ioutil"    "net/http"   "strings"   "sync")  func main() {  wg := sync.WaitGroup{}  for i := 1; i <= 100000; i++ {  if i%100 == 0 {  wg.Wait()  }  wg.Add(1)  go func() {  defer wg.Done()  insert()  }()  }  wg.Wait()  
}  func insert() {  url := "http://localhost:9201/cd/_doc"  method := "POST"  id := uuid.New().String()  payload := strings.NewReader(`{  "info":"` + id + `",  "email":"12345@136.com",  "name":{    "firstName":"张",  "lastName":"四"  },  "age":18}`)  client := &http.Client{}  req, err := http.NewRequest(method, url, payload)  if err != nil {  fmt.Println(err)  return  }  req.Header.Add("Content-Type", "application/json")  res, err := client.Do(req)  if err != nil {  fmt.Println(err, "错误了", id)  return  }  defer res.Body.Close()  body, err := ioutil.ReadAll(res.Body)  if err != nil {  fmt.Println(err)  return  }  if res.StatusCode != 201 {  fmt.Println(string(body), res.StatusCode, id)  }  
}

程序启动后,就开始并发的往集群中进行插入,此时我手动进入es03容器内部,然后kill掉了es进程。接着,此时索引的主副分片发生了变化,如下图所示,索引的主分片变到了节点es01上,而集群的master节点变成了es02。

Pasted image 20240315182242.png

整个程序此时还在进行,并未有任何报错。

此时我又手动重启了挂掉的es03,让其自动进行恢复recovery ,节点状态变化如下,可以看到es03已经变成副分片了。

Pasted image 20240315182838.png

最后,等待并发程序结束后,我向集群中对插入的数据行数进行查询,的确是10万条数据,说明数据没有发生丢失,并且,整个过程,客户端也没有报错。

Pasted image 20240315183036.png

足以说明,ES的主副分片的确对业务是无感知的了。的确是妙啊。对比起mysql的可靠性优先的主备切换方式,数据库会有小段的时间不可写,重试机制由ES帮我们做了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud Alibaba微服务从入门到进阶(六)(声明式HTTP客户端-Feign)

Feign是Netflix开源的声明式HTTP客户端&#xff08;只要声明一个接口&#xff0c;Feign就会通过你定义的接口自动给你构造请求的目标地址&#xff0c;并帮助你请求&#xff09; 用Feign重构前面RestTemplate方式的服务间调用 想回顾一下RestTemplate调用 加依赖 项目集成Feig…

最细节操作 Linux LVM 逻辑卷管理

Linux LVM&#xff08;逻辑卷管理&#xff09; 周末愉快&#xff0c;今天带大家实战一下LVM! 一、LVM理论 LVM&#xff0c;即Logical Volume Manager&#xff0c;逻辑卷管理器&#xff0c;是一种硬盘的虚拟化技术&#xff0c;可以允许用户的硬盘资源进行灵活的调整和动态管理…

2025武忠祥考研数学,视频百度网盘+基础全程课程PDF

“得数学者的天下”&#xff0c;25考研首先要开始的就是数学复习&#xff0c;而数学复习首先要开始的必然是高数&#xff01; 很多同学选择了跟着武忠祥老师学习高数&#xff0c;但是具体要怎么学&#xff1f;用什么书&#xff1f;怎么刷题&#xff1f;快来看看以 下的武忠祥…

广东省活动积温空间分布数据

广东省是中国大陆南端沿海的一个省份&#xff0c;位于南岭以南&#xff0c;属于东亚季风区&#xff0c;从北向南分别为中亚热带、南亚热带和热带气候&#xff0c;是中国光、热和水资源最丰富的地区之一。年平均气温约为19℃~24℃&#xff0c;1月平均气温约为16℃~19℃&#xff…

【运维】StarRocks数据迁移到新集群(针对于集群互通、不互通的情况)

文章目录 一. 迁移整体思路1. 对于新旧集群互通的情况2. 对于新旧集群不互通的情况 二、迁移过程&#xff08;两个集群互通的情况&#xff09;1. 备份过程1.1. 通过mysqlclient与starrocks进行关联1.2. 创建仓库与minio建立联系1.3. 备份数据到minio 2. 迁移过程2.1. 通过mysql…

YOLOv9改进策略:注意力机制 | 极化自注意力Polarized Self-Attention,效果秒杀CBAM、SE

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;本文针对Pixel-wise regression的任务&#xff0c;提出了一种更加精细的双重注意力机制——极化自注意力&#xff08;Polarized Self-Attention&#xff09;&#xff0c;效果优于CBAM、SE等经典注意力。 yolo…

R语言实现中介分析(1)

中介分析&#xff0c;也称为介导分析&#xff0c;是统计学中的一种方法&#xff0c;它用于评估一个或多个中介变量&#xff08;也称为中间变量&#xff09;在自变量和因变量之间关系中所起的作用。换句话说&#xff0c;中介分析用于探索自变量如何通过中介变量影响因变量的机制…

docker login 阿里云失败??

docker login 阿里云失败&#xff1f;&#xff1f; 首先参考 阿里云官方文档《Docker登录、推送和拉取失败常见问题》 看看是否是下面提到的情况&#xff1a; 我遇到的情况是超时: [rootk8snode1 software]# sudo docker login --usernametyleryun registry.cn-hangzhou.ali…

Spring Web MVC入门(2)

学习Spring MVC Postman介绍 在软件工程中, 我们需要具有前后端分离的思想, 以降低耦合性. 但是在测试后端代码时,我们还得写前端代码测试,这是个令人头疼的问题. 那么我们如何测试自己的后端程序呢, 这就用到了一个工具: Postman. 界面介绍: 传参的介绍 1.普通传参, 也就…

0基础 三个月掌握C语言(11)

字符函数和字符串函数 为了方便操作字符和字符串 C语言标准库中提供了一系列库函数 接下来我们学习一下这些函数 字符分类函数 C语言提供了一系列用于字符分类的函数&#xff0c;这些函数定义在ctype.h头文件中。这些函数通常用于检查字符是否属于特定的类别&#xff0c;例如…

阿里EMO模型:AI生成表情丰富的视频

引言 在数字多媒体的时代&#xff0c;人们对于互动性和个性化视频内容的需求不断增长。阿里巴巴的EMO&#xff08;Emote Portrait Alive&#xff09;模型&#xff0c;作为一项前沿的人工智能技术&#xff0c;正引领着这一领域的革新之路。 EMO模型概述 EMO模型是阿里巴巴智能计…

linux下重启ORACLE

切换到oracle用户 su - oracle 登录oracle sqlplus / as sysdba 启动数据库 startup 退出数据库 exit 启动监听 lsnrctl start FINISH

论文阅读——Rein

Stronger, Fewer, & Superior: Harnessing Vision Foundation Models for Domain Generalized Semantic Segmentation 一、引言 是一个对Domain Generalized Semantic Segmentation (DGSS)任务的视觉大模型的微调方法&#xff0c;即Rein。 Rein 专为 DGSS 任务量身定制&a…

matlab 眼球图像处理血管提取

1、内容简介 略 69-可以交流、咨询、答疑 2、内容说明 眼球图像处理血管提取 lab颜色空间提取眼球边缘、形态学操作 八邻域搜索算法 pUnImage&#xff0c;任意一点的坐标记为p(x,y),该点周围八邻域点的坐标记为p0(x,y)&#xff0c;p1(x,y)&#xff0c;p2(x,y)&#xff0c;…

利用express从0到1搭建后端服务

目录 步骤一&#xff1a;安装开发工具步骤二&#xff1a;安装插件步骤三&#xff1a;安装nodejs步骤四&#xff1a;搭建启动入口文件步骤五&#xff1a;启动服务器总结 在日常工作中&#xff0c;有很多重复和繁琐的事务是可以利用软件进行提效的。但每个行业又有自己的特点&…

【Redis】基于Redis实现查询缓存

1.缓存更新策略 主动更新用的最多。  主动更新一般是由缓存的调用者&#xff0c;在更新数据库的同时&#xff0c;更新缓存。 操作缓存和数据库时有三个问题需要考虑&#xff1a; 删除缓存还是更新缓存&#xff1f; 更新缓存&#xff1a;每次更新数据库都更新缓存&#xff0…

mac电脑修改终端zsh显示的用户名

电脑名称一直没有修改&#xff0c;所以电脑名称都是Apple的MacBook Pro&#xff0c;如下图所示&#xff1a; mac电脑终端显示用户名太长一点也不美观&#xff0c;而且占用很长的行&#xff0c;浪费空间&#xff0c;可以通过修改来调整要显示什么内容&#xff1a; 方式一 要想换…

2核4g服务器够用吗?

2核4G服务器够用吗&#xff1f;够用。阿腾云以2核4G5M服务器搭建网站为例&#xff0c;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&am…

Day66:WEB攻防-Java安全SPEL表达式SSTI模版注入XXEJDBCMyBatis注入

目录 JavaSec搭建 Hello-Java-Sec搭建 Java安全-SQL注入-JDBC&MyBatis Java安全-XXE注入-Reader&Builder Java安全-SSTI模版-Thymeleaf&URL Java安全-SPEL表达式-SpringBoot框架 知识点&#xff1a; 1、Java安全-SQL注入-JDBC&MyBatis 2、Java安全-XXE注…

综合实验---Web---进阶版

实验配置&#xff1a; 7-1为内网Nginx服务器&#xff1b;7-2和7-3为Web服务器&#xff1b;7-4为网关服务器&#xff1b;7-5为外网客户机&#xff1b; yum安装Nginx&#xff1b;yum安装Mysql&#xff1b; 编译安装PHP&#xff1b;编译安装 由于我们Nginx和Mysql都是yum安装&…