关于 Elasticsearch 段合并,这一篇说透了!

r660926
发布于 2022-4-25 17:33
浏览
0收藏

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区
这个涉及到基础概念,为保证说法的准确性,如下会贴上官方链接和其他来源地址,以便更深入理解好段合并的相关知识。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区

 

如图所示,自顶向下看,

 • 一个集群包含1个或多个节点;
 • 一个节点包含1个或多个索引;
 •  一个索引:类似 Mysql 中的数据库;
 • 每个索引又由一个或多个分片组成;
 • 每个分片都是一个 Lucene 索引实例,您可以将其视作一个独立的搜索引擎,它能够对 Elasticsearch 集群中的数据子集进行索引并处理相关查询;
每个分片包含多个segment(段),每一个segment都是一个倒排索引。


在查询的时,会把所有的segment查询结果汇总归并为最终的分片查询结果返回。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区


在 lucene 中,为了实现高索引速度,故使用了segment 分段架构存储。

 

一批写入数据保存在一个段中,其中每个段是磁盘中的单个文件。

 

由于两次写入之间的文件操作非常繁重,因此将一个段设为不可变的,以便所有后续写入都转到New段。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区


由于自动刷新流程每秒会创建一个新的段(由动态配置参数:refresh_interval 决定),这样会导致短时间内的段数量暴增。

 

而段数目太多会带来较大的麻烦。

 

 • 消耗资源:每一个段都会消耗文件句柄、内存和cpu运行周期;

 

 • 搜索变慢:每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢

 

Elasticsearch 通过在后台进行段合并来解决这个问题。

 

小的段被合并到大的段,然后这些大的段再被合并到更大的段。

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区

段合并的时候会将那些旧的已删除文档从文件系统中清除。

 

被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。

 

启动段合并不需要你做任何事。进行索引和搜索时会自动进行。

 

 • 当索引的时候,刷新(refresh)操作会创建新的段并将段打开以供搜索使用。

 

 • 合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中。这并不会中断索引和搜索。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区

 • 索引段的个数越多,搜索性能越低并且消耗更多的内存。


 • 索引段是不可变的,你并不能物理上从中删除信息。


可以物理上删除document,但只是做了删除标记,物理上并没有删除。

 

 • 当段合并时,这些被标记为删除的文档并没有被拷贝至新的索引段中,这样,减少了最终的索引段中的 document 数目。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区
 • 减少索引段的数量并提高检索速度;

 

 • 减少索引的容量(文档数)

 

原因:段合并会移除被标记为已删除的那些文档。

 

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区 • 磁盘IO操作的代价;


 • 速度慢的系统中,段合并会显著影响性能。

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区


早期版本的文档有说明如下:

 

optimize API(现在已废弃,原理一致)

 

optimize API大可看做是 强制合并 API。它会将一个分片强制合并到 max_num_segments 参数指定大小的段数目。

 

这样做的意图是减少段的数量(通常减少到一个),来提升搜索性能。

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区

并资源消耗——针对问题2


资源消耗的官方解读

 

orce merge should only be called against an index after you have finished writing to it. Force merge can cause very large (>5GB) segments to be produced, and if you continue to write to such an index then the automatic merge policy will never consider these segments for future merges until they mostly consist of deleted documents. This can cause very large segments to remain in the index which can result in increased disk usage and worse search performance.

 

一句话:导致磁盘io消耗和影响检索性能。

 

Force merge API

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html

 

以下是老版本文档解读,原理一致可参考,api已过时。

 

段合并

 

https://www.elastic.co/guide/cn/elasticsearch/guide/current/merge-process.html

 

请注意,使用 optimize API 触发段合并的操作不会受到任何资源上的限制。

 

这可能会消耗掉你节点上全部的 I/O 资源, 使其没有“富裕”资源来处理搜索请求,从而有可能使集群失去响应。

 

如果你想要对索引执行 optimize,你需要先使用分片分配(查看 迁移旧索引)把索引移到一个安全的节点,再执行。

 

是的,非常耗费资源,建议在非业务密集实践操作。

 

我的线上环境,我都是凌晨1点段合并(脚本控制,晚上没人操作系统)

关于 Elasticsearch 段合并,这一篇说透了!-鸿蒙开发者社区
 • 减少段的产生频率,修改refresh_inteval:默认1s,如果时效性要求不高,建议改成30s。


 • index.merge.scheduler.max_thread_count:根据cpu核数修改


推荐:

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html

 

 • 老版本参数修改参考价值不大,也建议看一下:


索引性能技巧

 

https://www.elastic.co/guide/cn/elasticsearch/guide/current/indexing-performance.html#segments-and-merging

分类
收藏
回复
举报
回复
    相关推荐