ES recovery、主副分片复制会有一段时间block写入?

简介: ES在主副本分片复制时候不会block写入(version > 2.x)ES在recovery主分片时候会有一段时间block写入

背景:

ES recovery、主副分片复制会有一段时间block写入?

先说结论:

1.ES在主副本分片复制时候不会block写入(version > 2.x)

2.ES在recovery主分片时候会有一段时间block写入

主副分片同步(新增副本分片)(该部分来自于:参考2)

1.在ES 2.0 版本之前,副本recovery要经历三个阶段:需要block写一段时间(这也是最容易实现一致性的流程)(此时translog还是只有一个大文件)

流程:
phase1:主分片的lucene做快照,发送到target节点。期间不阻塞写操作,在此拷贝期间新增的数据会写到主分片的translog中。
phase2:将主分片translog做快照,发送到target节点进行重放,重放期间不会阻塞写操作。
phase3:为主分片加写锁,此时会block写入,将剩余的translog发送到target节点。由于此时数据量很小,写入过程的阻塞时间很短。

从phase1开始,就要阻止lucene执行commit操作,避免translog被刷盘后清除。
后续版本去掉了phase3的这个过程,也就意味着不再需要block写入;

2.ES2.x及之后版本
translog被重构,允许多个文件,在translog允许多文件的场景下,也就意味着允许recovery保留所需的文件,同时允许engine执行flush,以及执行lucene的commit(这将创建一个新的translog文件);
引入了translog.view概念,view是一个引用,包含了包括所有当前未提交的translog文件,以及所有未来新创建的translog文件,直到view关闭;因此可以通过该view做operations的遍历操作;
不再需要block写入的阶段,通过将拷贝期间的写入操作同时转发到正在建立的副本分片(多写)来避免copy translog过程中的实时写入数据不能被副本获取的情况,从而保证主副一致;

流程:
创建一个Translog.view,用来重放operations;
phase1:将主分片的lucene做快照,发送到target。期间允许索引操作和flush操作。发送完毕后,告知target启动engine,engine启动(副本的lucene)后,即phase1即将结束(phase2开始之前),新的索引操作都会转发副分片正常执行
phase2:将主分片的translog做快照,发送到target去重放;

完整性:
phase2对translog的快照包含了从phase1开始的新增操作。而phase1即将结束、phase2开始之前,副分片已经可以正常处理写操作,只要把phase2的translog重放(主要是为了恢复phase1中target的engine未启动之前主分片写入的数据),就可以保证副分片不丢数据;

image.png

一致性:
由于没有了阻塞写操作的第三阶段,接下来的问题就是解决phase1和phase2之间的写操作,与phase2重放操作之间的时序和冲突问题。在phase1执行完毕后,副分片已经可以正常处理写请求,副分片的新增写操作和 translog重放的写操作是并行执行的。如果translog重放慢,又把他写回老数据怎么办(translog的数据覆盖掉新写入/更新的数据)?
es现在的机制是在写操作(新增、更新、删除)中做异常处理。新增不存在冲突,只需要判断update、delete操作的版本号是否小于lucene中doc的版本号,大于才能操作;
注:Index,Delete,都继承自Operation,每个Operation都有一个版本号,这个版本号就是lucene中doc版本号;

ES在recovery

1.recovery副本分片
副本分片从node1,move到node2的流程:
1.master节点将该副本分片标记成relocating状态,此时从主分片开始拷贝lucene文件到node2(拷贝完成之后启动node2副本分片的lucene引擎),然后走主副本分片同步数据的逻辑(如上描述);
2.完成后该副本被标记为started,然后node1中的副本分片进行删除,完成此次recovery。
注:copy过程中写入是会写到3个分片上(主、副本、recovery后的副本),‘recovery后的副本’是在阶段2(阶段1的文件拷贝完成、lucene启动后)才接受写入。
recovery副本分片的场景:相当于直接增加一个副本分片,然后再下掉老的副本分片;

image.png

此过程不会block写入;

2.recovery主分片
primary分片从node0,move到node1的过程:
1.master节点下发状态,将该主分片标记relocating,更新routing_table和routing_nodes;
2.target分片会开始复制primary的lucene文件块;此时写入请求到达source节点时,会正常写入到source主分片中(不会同时写到target)。
注意:在分片的整个relocating过程中,对target节点的请求都会被转发到source节点,直到target节点应用了master下发的分片变为STARTED的集群状态
3.lucene文件拷贝完成后进入下一阶段。该阶段主要是target分片复制translog,并重放translog
该阶段收到的写入请求后复制给target节点(将target分片加入到 replication group)(即source分片写入、target分片也写入)。
4.tranlog复制并重放完成意味着数据已经对齐,进入下一阶段(handoff阻塞阶段)。该阶段是为了完成主分片状态的转移,该阶段对收到的写入请求放到队列(delayedOperations)中,写入流程结束,但是不会返回响应给client,待主分片状态转移完成后继续执行,最多阻塞30分钟。delayedOperations中的操作会在本阶段的阻塞过程结束后处理
注:该阶段时间很短,只是修改一个状态,使写入进入阻塞;
5.最后一个阶段是执行失败重试的逻辑,该阶段主要是target分片向master节点发送变更状态为started请求,并等待master下发状态变更;
上一步的阻塞阶段虽然时间很短,但是依然会有写入,delayedOperations中的数据在进入该阶段的时候处理;与该阶段的写入请求是统一的处理逻辑。
处理逻辑:
该阶段的写入请求和delayedOperations中的请求都会执行失败,抛出 ShardNotInPrimaryModeException异常,并捕获该异常,等待1分钟后重试写入,再次失败则退出;
如果1分钟内收到了新的集群状态,也会重试写入,然后写入成功。

补充解释:阻塞和失败重试阶段时间都比较短,但是完成了很多事情,阻塞阶段刚开始是primary分片开始阻塞写入,并告诉target分片可以开始变更分片状态了,此时的写入全部进入队列;
target分片响应了(primary分片接受响应)之后,开始进入“失败重试阶段”;
注:primary接受handoff响应做了什么事情?取消阻塞状态,将primary是主分片的标记清除(也就是说ES不再认为该分片是主分片)
primary开始向target发送recovery结束的消息,target分片接受到消息之后,认为自己可以成为主分片了,所以开始向master节点请求将分片标记为started状态;
master节点收到请求之后立刻下发状态变更命令,target分片状态变更完成之后,整个流程结束;
在此期间的写入请求会因为source(primary)分片已经不是主分片状态了,全部报错(但是不返回客户端),等待一分钟后重试;

图片来自参考1:
image.png

参考:
1.https://blog.51cto.com/u_15162069/2883927
2.https://www.easyice.cn/archives/231#i-2

相关文章
|
架构师 NoSQL Java
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
|
Java 网络性能优化 微服务
让Elasticsearch飞起来!——性能优化实践干货
Elasticsearch性能优化的最终目的:用户体验爽。爽点就是:快、准、全!关于Elasticsearch性能优化,阿里、腾讯、京东、携程、滴滴、58等都有过很多深入的实践总结,都是非常好的参考。本文换一个思路,基于Elasticsearch的爽点,进行性能优化相关探讨。
8869 0
让Elasticsearch飞起来!——性能优化实践干货
|
11月前
|
消息中间件 算法 调度
分布式系统学习10:分布式事务
本文是小卷关于分布式系统架构学习系列的第13篇,重点探讨了分布式事务的相关知识。随着业务增长,单体架构拆分为微服务后,传统的本地事务无法满足需求,因此需要引入分布式事务来保证数据一致性。文中详细介绍了分布式事务的必要性、实现方案及其优缺点,包括刚性事务(如2PC、3PC)和柔性事务(如TCC、Saga、本地消息表、MQ事务、最大努力通知)。同时,还介绍了Seata框架作为开源的分布式事务解决方案,提供了多种事务模式,简化了分布式事务的实现。
501 5
|
存储 监控 测试技术
Agent Workflow
【6月更文挑战第25天】
946 3
|
存储 SQL Oracle
关系型数据库文件方式存储DATA FILE(数据文件)
【5月更文挑战第11天】关系型数据库文件方式存储DATA FILE(数据文件)
487 3
|
Linux
elasticsearch启动报错:unable to install syscall filter: java.lang.UnsupportedOperationException: seccomp
elasticsearch启动报错:unable to install syscall filter: java.lang.UnsupportedOperationException: seccomp
237 0
|
存储 编译器 数据处理
栈溢出及解决方法
栈溢出及解决方法
|
开发者 索引
使用 elasticdump 跨版本迁移 ES 数据
使用 elasticdump 跨版本迁移 ES 数据
使用 elasticdump 跨版本迁移 ES 数据
|
算法 网络协议 机器人