Merge 流程源码分析

简介: 本文介绍了Elasticsearch写入流程中的关键阶段,包括路由写请求、数据写入主分片与副本、refresh、flush及segment合并等操作,详细说明了各阶段的工作机制及优化配置项,帮助理解数据从写入到可搜索的全过程。

1、客户端写请求发送到协调节点(Coordinating Node)

2、协调节点路由写请求到活跃的shard中。路由规则:(实现类OperationRouting)

  2.1  默认: hash(document_id)/(主shard数)

  2.2 根据指定字段的值作为路由参数: hash(参数值)/(主shard数)。思考:分母为什么是主shard数?主要是因为写入时需要先写入主shard中。然后再同步到副shard中去。

3、数据先写入主分片的memory buffer中,然后再写入到transaction log(默认同步,也可配置为异步),当主分片中的请求全部返回成功后,再并行写入到副分片中。当主副本全部写入成功后即返回到客户端。此时数据是不能被搜索的。只能通过id在trans log中提取。

4、refresh阶段: memory buffer会周期性(默认1s)的做refresh操作。将内容写入到一个新的segment中。此阶段对应lucene的flush阶段。故此时数据可以被搜索。但并没有落盘持久化。

5、flush阶段: 每隔30分钟或者当trans log中的数据量太大时,会产生一次flush操作。该操作会清空内存缓冲区,从而产生一个新的segment,触发一个lucene的commit操作,落盘产生一个commit point点(就是备份)。此时trans log就可以被清除了。

6、segment合并阶段: lucene会定期merge一些小的segment至一个大的segment中。防止segment太多,占用太多文件句柄及降低查询效率。

2、refresh阶段

2.1 流程

refresh阶段主要是将之前写入缓冲区的数据,刷成一个新的segment。保证数据可搜索。这个刷新的频率,影响搜索的实时性。

具体过程如图:

1、数据写入内存缓冲区和translog

2、数据refresh成一个segment, 同时清空缓冲区的内容。此时的segment没有落盘。但同样是可搜索的

2.2 配置项及api

缓冲区属于节点级别的资源,节点上的所有shard共享。关于缓冲区大小的配置如下:

indices.memory.index_buffer_size 缓冲区大小。默认是节点总堆的10%。也可配置为绝对值。

indices.memory.min_index_buffer_size 如果index_buffer_size为百分比,则该参数可设置缓冲区最小值。默认48mb。

indices.memory.max_index_buffer_size 如果index_buffer_size为百分比,则该参数可设置缓冲区最大值。默认无界。

缓冲区刷新频率的配置:

refresh_interval 刷新频率。默认每秒刷新一次。 设置为-1为关闭刷新。

接口:

代码语言:txt

AI代码解释

POST /blogs/_refresh 指定索引刷新
POST /_refresh 全部手动
PUT /my_logs/_settings 关闭自动刷新
{ "refresh\_interval": -1 }
PUT /my_logs/_settings 每秒刷新1次
{ "refresh_interval": "1s" }

3、flush阶段

3.1 流程

1、每30分钟或者当translog中的数据达到阈值后,会触发一次flush操作。产生一个point点。并落到磁盘。

2、commit point点产生,会清空内存缓冲区及translog数据

3.2 配置项及api

translog相关配置

代码语言:txt

AI代码解释

index.translog.sync_interval 刷新频率。默认5s,不能低于100ms
index.translog.durability 刷新方式。默认request(同步), async 异步
index.translog.flush_threshold_size flush阶段的translog阈值。默认512mb。如果达到则会强制flush,否则需要等待30分钟
index.translog.retention.size 保留的translog大小。默认512mb
index.translog.retention.age 保留的translog时间。默认12h

上面2个translog保留的配置可能会用于副本的恢复。不会影响写入性能。

代码语言:txt

AI代码解释

index.translog.generation_threshold_size 单个独立translog的大小阈值,如果超过则生成新的translog,不flush。默认64mb。
flush api可以针对单个或者所有索引进行flush
POST /twitter/_flush/synced
POST /blogs/_flush
POST /_flush?wait_for_ongoing 同步刷新
异步,5s频率
PUT /my_index/_settings
{
"index.translog.durability": "async",
"index.translog.sync\_interval": "5s"
}

4、merge阶段

4.1 流程

1、将refresh和flush产生的segment进行合并,合并成一个大的segment。合并过程中的segment仍可以被搜索。如下图:

2、合并完成后会进行一个flush操作。产生一个新的commit point点。同时将已合并的segment删除。

4.2 配置&算法

配置汇总

代码语言:txt

AI代码解释

index.merge.policy.floor_segment 最小参考的segment的大小,并非实际最小segment的大小。默认设置为2mb
index.merge.policy.max_merge_at_once 单次合并的最大segment数量。默认是10个
index.merge.policy.max_merged_segment 合并时的最大segment阈值,大于该阈值的正常不会合并。除非触发了第3种情况的合并规则。默认5gb
index.merge.policy.segments_per_tier 每层的segment数量
index.merge.policy.deletes_pct_allowed segment中文档删除百分比。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge
index.merge.scheduler.max_merge_count 最大merge次数
index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30

es中的合并分为3种类型:

 1)NATURAL:  常规合并。合并一些小于指定segment阈值以内的segment。使其成为一个大的segment。提高index效率。es自动完成。

 2)  FORCE_MERGE_DELETES:合并一些大于指定segment阈值且包含大量已删除文件的segment。也就是给大segment "瘦身" , es自动完成。

 3)FORCE_MERGE:  手动强制合并。通过api接口调用。一般情况不需要使用。

注意:所有算法中,标注颜色的变量均是配置项,即可调优参数。

4.2.1 NATURAL
配置

代码语言:txt

AI代码解释

index.merge.policy.floor_segment 最小参考的segment的大小,并非实际最小segment的大小。默认设置为2mb
index.merge.policy.max_merge_at_once 单次合并的最大segment数量。默认是10个
index.merge.policy.max_merged_segment 合并时的最大segment阈值,大于该阈值的正常不会合并。除非触发了FORCE_MERGE_DELETES合并规则。默认5gb
index.merge.policy.segments_per_tier 每层的segment数量。
index.merge.policy.deletes_pct_allowed segment中文档删除百分比。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge
index.merge.scheduler.max_merge_count 最大merge次数
算法

1、根据 segment大小倒序排列剔除不符合条件的segment

   1) 正在参与合并操作的segment

   2) segment大小大于maxMergedSegmentBytes/2(maxMergedSegmentBytes默认5g)且segment中删除文档的比例较低的segment(segDelPct <=deletesPctAllowed)

2、计算触发merge条件的segment数(allowedSegCount),如果实际待merge的segment数小于该值则不会触发合并。具体算法:

假设如下配置:  floorSegmentBytes = 2*1024*1024 , segsPerTier= 10, maxMergeAtOnce= 20,maxMergedSegmentBytes= 50*1024*1024

  索引中最小: segment:minSegmentBytes = 1  1024  1024

  索引大小:totIndexBytes = 500  1024  1024

  则allowedSegCount = 26;

3、从待合并的segment列表中分层提取segment进行merge。直到待合并的segment列表中的元素小于 allowedSegCount 时,则中止此次合并。

  1)每层中segment的大小总和不得超过maxMergedSegmentBytes

  2)每层中segment的个数不得超过mergeFactor

代码语言:javaaly.mcmajans.com

AI代码解释

`final int mergeFactor = (int) Math.min(maxMergeAtOnce,segsPerTier);`

  3)层的个数不得超过max_merge_count

    由于待合并的segment是倒序排列,则合并的原则总是优先合并满足条件的大的segment。

例如: maxMergedSegmentBytes = 5G, 则蓝色是可以合并,红色是不能合并的。如下图:

4.2.2 FORCE_MERGE_DELETES

对segment中已删除文档的比例大于deletes_pct_allowed阈值的segment进行合并

配置aly.yaziyooo.com77

代码语言:txt

AI代码解释

index.merge.policy.deletes_pct_allowed segment中文档删除比例的阈值。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge。
index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30
算法

1、查找所以segment中是否存在已删除的文档比例大于deletes_pct_allowed阈值且处于未合并状态的segment。如果有,则继续。没有,则返回。

2、对所有segment根据大小按照降序排序 并 剔除不符合的segment。

 1)正在参与合并的segment

 2)  已删除的文档比例小于 deletes_pct_allowed的segment

注意:这里没有剔除大于maxMergedSegmentBytes / 2的segment。这是和常规合并最大的区别。

3、从待合并的segment列表中分层提取segment进行merge。直到合并所有的待合并segment,则中止此次合并。这里的中止条件和常规合并的不一致。

  1) 当前层中存在多个segment时,此层中segment的大小总和不得超过 maxMergedSegmentBytes。

  2)  当前层中存在单个segment时,此层中的segment大小没有限制。可以大于maxMergedSegmentBytes,也可以小于maxMergedSegmentBytes。

 3)每层中segment的个数不得超过 maxMergeAtOnceExplicit

注:由于待合并的segment是倒序排列,则合并的原则总是优先合并满足条件的大的segment。和常规合并的策略一致。

4.2.3 FORCE_MERGE
配置

代码语言:txt

AI代码解释

index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30
max_num_segments 最终合并的segment个数,通过api参数指定。
api 如下:
POST /test/_forcemerge?only_expunge_deletes=false&max_num_segments=100&flush=true
算法 aly.tas1000.com55

1、对所有segment根据大小按照降序排序 并 剔除不符合的segment。

   1) 正在合并中的segment

   2) 大于mergeBytes的segment

2、计算合并后的单个segment大小上限(maxMergeBytes)。可以看到当指定只合并成1个segment时,maxMergeBytes基本是接近无限大的。**

    最小也是maxMergedSegmentBytes的1.25倍。最大就看指定合并后的segment个数和总的待合并的大小

3、从待合并的segment列表中分层提取segment进行merge。直到合并所有的待合并segment,则中止此次合并。`这里的中止条件和常规合并的不一致。

1)单层合并

        1、待合并的segment个数小于max_merge_at_once_explicit

        2、只合并成1个segment。

        3、待合并的segment总大小 小于  maxMergeBytes

2)分层合并  

  1) 当前层中存在多个segment时,此层中segment的大小总和不得超过 maxMergeBytes。

相关文章
|
SQL 分布式计算 NoSQL
【SQL 审核查询平台】Archery使用介绍
【SQL 审核查询平台】Archery使用介绍
1510 0
【SQL 审核查询平台】Archery使用介绍
|
5月前
|
SQL 关系型数据库 MySQL
击穿 MySQL 事务隔离级别:底层实现原理 + 生产级架构选型避坑指南
本文深度解析MySQL事务隔离级别,从SQL标准定义出发,结合InnoDB底层的MVCC、undo log、Read View与锁机制,详解脏读、不可重复读、幻读三大异常及4种隔离级别的实现差异,辅以可复现SQL示例与Spring Boot实战代码,提供生产环境选型指南与避坑方案。
392 1
|
7月前
|
人工智能 安全 Java
Java 开发者福音:无影 AgentBay 官方 Java SDK 正式发布,无缝集成 Spring AI 与 LangChain4j
阿里云无影AgentBay推出Java SDK,助力Java应用安全接入AI Agent。通过云端沙箱隔离执行环境,解决本地执行的安全、并发与依赖难题,支持Spring AI、LangChain4j等主流框架,实现高并发、可扩展的智能体开发。
1047 6
|
人工智能 自然语言处理 监控
2025年如何通过SOP工具实现流程标准化?详解6大构建步骤及7款软件选型指南
标准作业程序(SOP)是企业核心知识资产与效率引擎,其科学构建和高效落地成为2025年数字化转型的关键。本文解析SOP全生命周期流程,探讨可视化技术对流程管理的赋能,并推荐7款智能工具。从概念到实施,SOP助力企业实现技术储备、效率提升与风险防控。通过动态协同、富媒体化及AI增强,企业可在高效与创新间取得平衡,构建可持续竞争优势。
4703 2
|
传感器 监控 数据中心
|
人工智能 自然语言处理 搜索推荐
AI 搜索 MCP 最佳实践
本文介绍了如何通过 MCP 协议,快速调用阿里云 OpenSearch 、ElasticSearch 等工具,帮助企业快速集成工具链、降低开发复杂度、提升业务效率。
796 1
|
存储 缓存 分布式计算
OSS大数据分析集成:MaxCompute直读OSS外部表优化查询性能(减少数据迁移的ETL成本)
MaxCompute直读OSS外部表优化方案,解决传统ETL架构中数据同步延迟高、传输成本大、维护复杂等问题。通过存储格式优化(ORC/Parquet)、分区剪枝、谓词下推与元数据缓存等技术,显著提升查询性能并降低成本。结合冷热数据分层与并发控制策略,实现高效数据分析。
482 2
|
分布式计算 数据库
Mapreduce中的Mapper&reducer
【9月更文挑战第19天】在 MapReduce 框架中,Mapper 和 Reducer 是处理大规模数据集的关键组件。Mapper 负责将输入数据分割成键值对,而 Reducer 则对这些键值对进行汇总处理,生成最终结果。两者通过并行处理和分布式计算协同工作,Mapper 将数据转换为键值对,Reducer 对相同键的值进行聚合。开发人员需实现相应接口并编写定制逻辑,以充分利用框架优势,处理大规模数据集并获得有价值的结果。
913 8
|
开发框架 自然语言处理 API
基于RAG搭建企业级知识库在线问答
本文介绍如何使用搜索开发工作台快速搭建基于RAG开发链路的知识库问答应用。
9752 17
|
SQL JSON 分布式计算
Spark SQL底层执行流程详解(一)
Spark SQL底层执行流程详解
1510 0
Spark SQL底层执行流程详解(一)

热门文章

最新文章