为什么我的 Amazon Elasticsearch Service 集群中的“已删除文档”指标如此高?

上次更新时间:2020 年 7 月 14 日

我已删除 Amazon Elasticsearch Service (Amazon ES) 集群中的文档,但未回收任何磁盘空间。我如何释放更多磁盘空间?

简短描述

在 Amazon ES 中,DeletedDocuments 指标是一个计数器,它显示标记为删除的文档数量。在处理删除请求并在 Elasticsearch 集群中合并索引分段之后,该指标将显示数量增加。

在例行清理期间,Amazon ES 会自动运行强制合并操作。在强制合并期间,现有分段将合并到新分段中,并且新请求也会将现有分段写入其中。虽然强制合并不会清除任何已删除的文档,但是该操作可通过减少 Elasticsearch 集群中的索引分段数来节省磁盘空间。

要在回收 Elasticsearch 集群中的磁盘空间时维护索引元数据,请考虑以下方法:

要立即回收磁盘空间,您也可以删除索引,而不是删除各个文档。删除索引不会创建任何删除标记。因此,将立即回收磁盘空间。

解决方法

检查已删除文档的数量

要检查 Elasticsearch 集群中的已删除文档的数量,请运行集群统计 API。从集群统计 API 调用获得的值将显示在 Elasticsearch 集群的 DeletedDocuments 指标中。

输出将返回 Elasticsearch 集群中所有索引的已删除文档的总和。可以使用响应输出中的“docs.deleted”字段检查此计数。

例如,如果集群具有三个索引(index1、index2 和 index3),则可以运行索引统计 API 调用:

GET index1/_stats
…
"docs" : {
        "count" : 100,
        "deleted" : 1
      }
… 
GET index2/_stats
…
"docs" : {
        "count" : 100,
        "deleted" : 5
      }
… 
GET index3/_stats
…
"docs" : {
        "count" : 100,
        "deleted" : 8
      }
… 

然后,集群统计 API 调用将为 Elasticsearch 集群中的所有索引添加“docs.deleted”字段:

…
"docs" : {
      "count" : 1227677521,
      "deleted" : 14
    } 
…

如果删除 index2,则集群统计 API 调用将仅计算 index1 和 index3 的值:

GET _cluster/stats
…
"docs" : {
      "count" : 1227677521,
      "deleted" : 9 
    } 

现在,将合并这些分段,并删除 index2 的索引元数据。因此,DeletedDocuments 指标值将降至 9。

确认您的文档大小

要检查文档大小和索引计数,请使用 cat 索引 API。确保新文档的大小与 Elasticsearch 集群中现有文档的大小相同。使用相同的文档大小可确保已删除的文档不会占用额外的磁盘空间。相反,Amazon ES 会在后台工作以释放磁盘空间,合并分段并自动删除任何已删除的文档。

清除已删除的文档

要手动回收磁盘空间,请运行强制合并 API 并将 only_expunge_deletes 参数设置为“true”:

POST /<index-name>/_forcemerge?only_expunge_deletes=true

当您执行强制合并时,旧分段将合并到新分段中,并且 Amazon ES 会自动清除任何已删除的文档。结果,强制合并将减少使用的磁盘空间量。创建新分段后,旧分段将被删除。有关更多信息,请参阅 Elasticsearch 网站上的 Lucene 对已删除文档的处理

减少 Elasticsearch 集群中的文档数量

要减少 Elasticsearch 集群中的文档数量(不禁用任何写入操作),请单独使用强制合并。但是,请注意以下事项:

  • 仅当有足够的可用存储空间时,才对 Elasticsearch 集群执行强制合并。该操作是资源密集型操作。
  • 强制合并操作将触发一个 I/O 密集型进程,并阻止对集群的所有新请求,直到合并完成。
  • 当没有其他数据写入索引时,应仅针对只读索引调用强制合并操作。如果针对读/写索引调用强制合并,则该操作会导致生成非常大的分段(每个分段大于 5Gb)。然后,自动合并策略不会考虑在未来合并这些分段,除非这些分段主要由已删除的文档组成。因此,磁盘使用量会增加,并且搜索性能会下降。

您还可以使用按查询删除 API删除 API 来手动删除 Elasticsearch 集群中的任何文档。

立即回收磁盘空间

要立即回收磁盘空间,请使用删除索引 API。这将删除现有索引,并且有助于释放磁盘空间。

注意:最好删除未使用的旧索引。如果要删除活动索引,请确保阻止自动创建索引。有关更多信息,请参阅 Elasticsearch 网站上的自动创建索引