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

上次更新日期:2021 年 9 月 30 日

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

简短描述

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

OpenSearch Service 使用合并策略设置自动运行 merge(合并)API 操作。在合并过程中,较小的分段将合并为较大的分段以保证索引大小。此外还会删除标记为删除的文档,以释放额外的磁盘空间。

要立即回收磁盘空间,您可以删除索引,而不是删除各个文档。您也可以使用 force merge(强制合并)API 和 only_expunge_deletes 参数来清除索引中已删除的文档。

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

解决方法

检查已删除文档的数量

要检查 OpenSearch Service 集群中已删除文档的数量,请运行 cluster stats(集群统计)API。从 cluster stats(集群统计)API 调用获得的值将显示在集群的 DeletedDocuments 指标中。输出将返回您的集群中所有索引的已删除文档的总和。可以使用响应输出中的“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 调用会为集群中的所有索引添加“docs.deleted”字段:

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

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

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

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

确认您的文档大小

要检查文档大小和索引计数,请使用 cat indices(cat 索引)API。确保新文档的大小与 OpenSearch Service 集群中现有文档的大小相同。使用相同的文档大小可确保已删除的文档不会占用额外的磁盘空间。

清除已删除的文档

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

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

注意:此操作只会清除包含标记为删除的文档的分段。

因此,强制合并将减少使用的磁盘空间量。创建新分段后,旧分段将被移除,新分段将不再包含标记为删除的文档。有关已删除文档的更多信息,请参阅 Elasticsearch 网站上的 Lucene's handling of deleted documents

但是,在执行强制合并操作时,请注意以下几点:

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

您还可以使用 delete by query(按查询删除)API 或 delete(删除)API 来手动删除集群中的任何文档。

立即回收磁盘空间

要立即回收磁盘空间,请使用删除索引 API。删除索引不会创建任何删除标记。相反,删除索引 API 会清除索引元数据,并立即回收磁盘空间。回收的磁盘空间将反映在 DeletedDocuments 指标中。

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