首页 > 解决方案 > 为什么 Elasticsearch 中的段合并需要停止写入索引

问题描述

我正在寻找在 ES 最新版本中运行现在称为 forcemerge API 的优化(ES 1.X)。在阅读了一些类似thisthis的文章之后。似乎我们应该只在只读索引上运行它,引用官方 ES 文档:

仅应针对只读索引调用强制合并。针对读写索引运行强制合并可能会导致生成非常大的段(每段>5Gb)

但我不明白

  1. 在运行 forcemerge 或优化 API 之前将索引置于只读模式的原因。
  2. 正如上面的 ES 文档中所解释的,它可能会导致非常大的段,这不应该是我理解的情况,新的更新首先写入内存中,当刷新发生时写入段,那么为什么在 forcemerge 期间进行写入可以生产非常大的细分市场?

如果我们不想将索引置于只读模式并仍然运行强制合并以删除删除,是否有任何解决方法。

如果我需要提供任何其他信息,请告诉我。

标签: elasticsearchmergesegment

解决方案


forcemerge可以显着提高查询的性能,因为它允许您将现有数量的段合并为较少数量的段,这对于查询更有效,因为段是按顺序搜索的。合并时,所有标记为删除的文档也会被清理。

作为基于合并策略的 Elasticsearch 内务管理的一部分,合并会在后台定期自动进行。

棘手的事情是:合并策略只考虑最大 5 GB 的段。将 forcemerge API 与允许您指定结果段数的参数一起使用,您将面临结果段大于 5GB 的风险,这意味着将来的合并请求将不再考虑它们。只要您不删除或更新文档,就没有错。但是,如果您继续删除或更新文档,Lucene 会将现有段中的旧版本文档标记为已删除,并将新版本的文档写入新段中。如果您删除的文档位于大于 5GB 的段中,则不再对它们进行内务处理,即标记为删除的文档将永远不会被清理。

通过在执行强制合并之前将索引设置为只读,您可以确保您最终不会得到包含大量遗留文档的巨大段,这会消耗内存和磁盘中的宝贵资源并减慢查询速度。

Arefresh正在做一些不同的事情:您想要索引的文档首先在内存中处理,然后再写入磁盘是正确的。但是,允许您实际查找文档(“段”)的数据结构不会立即为每个文档创建,因为这将非常低效。仅当内部缓冲区已满或当refresh发生。通过触发刷新,您可以使文档立即可供查找。起初该段仍然只存在于内存中,因为 - 再次 - 在创建每个段后立即将其同步到磁盘将是非常低效的。内存中的段会定期同步到磁盘。即使您在同步到磁盘之前拔掉插头,您也不会丢失任何信息,因为 Elasticsearch 维护一个 translog,这将允许 Elasticsearch “重播”所有尚未进入磁盘段的索引请求。


推荐阅读