在读写索引上执行带only_expunge_deletes的forcemerge是否可行?
读写索引上执行带
only_expunge_deletes的forcemerge:风险与ES自动空间回收机制 直接给结论:不建议在读写(read-write)索引上执行带only_expunge_deletes参数的forcemerge操作,依然存在产生超大段的风险。下面详细解释原因,以及ES默认如何自动回收空间。
一、为什么带only_expunge_deletes的forcemerge在读写索引上仍有风险
先明确only_expunge_deletes的作用:它只会合并那些包含已删除文档的段,合并过程中会把这些段里的有效文档整合为新段,同时清理掉已删除的部分。但问题出在读写索引是动态的——它一直在接收新写入的数据:
- 当你手动触发这个操作时,合并出来的新段很可能会接近甚至超过ES默认的
index.merge.policy.max_merged_segment阈值(默认5GB)。一旦形成这种超大段,后续ES的自动合并策略会因为它已经达到了最大合并段大小,不会再主动对它进行合并。 - 如果后续这个超大段里又有大量文档被删除,由于它的尺寸已经超过阈值,ES不会轻易启动合并来清理这些删除内容,最终会导致分片里残留这种“占着大量磁盘空间但有效数据占比低”的超大段,和直接在读写索引上执行普通
forcemerge的风险本质一致。 - 除此之外,手动触发
forcemerge会抢占大量CPU和IO资源,严重干扰读写索引的正常业务操作(写入延迟升高、查询变慢)。
二、Elasticsearch默认如何自动回收空间
ES完全不需要依赖手动调用forcemerge来释放已删除文档占用的空间,它有一套成熟的自动机制:
- 后台自动段合并:ES的后台合并线程会持续监控段的状态,定期将小的段合并为更大的段,在合并过程中自动剔除已删除的文档,释放对应的磁盘空间。这个过程由
index.merge.policy系列参数自动调控,比如:index.merge.policy.expunge_deletes_allowed:默认值10%,当一个段中已删除文档的占比超过这个阈值时,ES会优先将其纳入合并计划,清理删除内容。index.merge.policy.max_merged_segment:控制合并后段的最大尺寸,默认5GB,避免出现过大的段影响性能。
- 段的生命周期流转:新写入的数据先存在内存缓冲区,刷盘后形成小的临时段;后台线程会逐步将这些小段合并成中等大小的段,最终合并为接近最大阈值的大段,全程自动清理删除内容。
- 只读索引的特殊处理:只有当索引变为只读(比如归档的冷数据索引,不再有写入操作)时,才适合调用
forcemerge(无论是否带only_expunge_deletes)。此时合并后的段不会再有新数据写入,能稳定优化段结构、回收空间,且不会影响业务。
内容的提问来源于stack exchange,提问作者user8808265
相关产品推荐
相关产品推荐

