深入理解 Elasticsearch 的核心工作原理:文档更新、删除与段合并

368 阅读5分钟

引言

在理解 Elasticsearch 的核心工作原理时,很多开发者可能会忽视一些关键的内部机制,比如文档更新、删除操作和段合并。这些操作在后台执行时,不仅影响索引的存储方式,也直接关系到查询性能和存储空间的管理。本文将深入探讨这些核心流程,帮助你理解 Elasticsearch 的底层实现以及如何优化你的 Elasticsearch 配置和性能。


1. Elasticsearch 中的段(Segment)

1.1 什么是段(Segment)?

在 Elasticsearch 中,段(Segment) 是 Lucene 用来存储索引数据的基本单位。你可以把它看作是一个不可变的倒排索引,每个段包含了 Elasticsearch 中一部分文档的索引和原始数据。

  • 倒排索引:段内部存储的是倒排索引,表示词条与文档之间的关系。
  • 文档数据:每个段还保存了与文档相关的元数据,如文档的字段内容和一些标识符。

下面是段的结构图:

Untitled diagram-2024-11-13-071749_副本.png

1.2 段的特点

  • 不可变性:段一旦写入,就不能修改或删除。即使你删除了文档,它仍会保留在原始段中,直到发生段合并。
  • 存储独立性:每个段都独立地存储在磁盘上,查询时,Elasticsearch 会遍历所有相关的段,查找匹配的文档。

段的结构使得 Elasticsearch 的索引能够高效地进行搜索,同时也便于 Elasticsearch 后台通过合并操作优化索引的存储和查询性能。


2. 文档的更新与删除

2.1 文档更新

在 Elasticsearch 中,文档的更新并不会直接覆盖原有文档。相反,Elasticsearch 会将更新后的文档作为一个新文档插入到索引中,并将旧文档标记为已删除。此时,原始文档和更新后的文档会在不同的段中存在。

  • 更新操作:当更新一个文档时,Elasticsearch 会创建一个新文档并将其存储在一个新的段中,原有文档会被标记为已删除。删除标记会在段合并过程中被清除。

2.2 文档删除

文档删除时,Elasticsearch 只会标记该文档为删除状态,并不会立刻从磁盘上移除它。删除操作只是将文档添加到一个 删除列表 中,直到段合并时才会清除。


3. 段合并(Segment Merge)

3.1 段合并的背景

随着 Elasticsearch 索引的增长,多个小段会被创建。这些小段的数量不断增加,会导致查询性能降低,因为 Elasticsearch 在查询时必须扫描所有相关的段。为了提高查询效率并减少存储开销,Elasticsearch 需要定期对这些小段进行合并,生成更大的段。

3.2 段合并的原理

段合并是一个后台自动进行的操作。合并的基本过程是将多个小段合并为一个更大的段,并移除已经标记为删除的文档。合并后的段通常会包含更多的文档,并且删除文档的空间会被释放。

  • 合并策略:Elasticsearch 会在后台监控段的数量,并自动决定何时合并段。合并会在系统负载较低时进行,以避免影响查询性能。
  • 减少存储空间:合并不仅减少段的数量,还通过清理删除标记,降低了存储空间的占用。

3.3 段合并的触发条件

Elasticsearch 在以下情况下会触发段合并:

  • 段数量过多:当一个索引中的小段数量达到一定阈值时,Elasticsearch 会启动段合并。
  • 合并策略:合并操作会选择大小合适的段进行合并,以优化性能和存储空间。
  • 后台执行:段合并是一个自动后台任务,不会影响前端的查询操作。

3.4 段合并的影响

  • 查询性能:通过减少小段的数量,查询时需要扫描的段数减少,从而提高查询速度。
  • 存储优化:删除标记的文档会被清除,释放磁盘空间。
  • 资源消耗:段合并会消耗 CPU 和 I/O 资源,因此可能会在合并期间影响集群的整体性能。Elasticsearch 会智能调节合并的频率和时机,以减少影响。

4. 如何优化段合并过程

4.1 配置段合并策略

Elasticsearch 提供了一些配置项,用来调节段合并的行为,包括:

  • index.merge.policy:控制合并操作的策略,涉及到最大段大小、最小合并条件等。
  • index.merge.max_merged_segment:控制合并后的最大段大小,避免单个段过大导致性能问题。
  • index.merge.scheduler:调节合并任务的调度策略,确保合并不会影响查询性能。

4.2 监控段合并

通过监控 Elasticsearch 的 _cat/indices API 和 _segment API,可以查看索引中段的数量和合并状态。通过调整合并配置,可以减少不必要的段合并操作,避免影响查询性能。


5. Elasticsearch 的核心工作流程

5.1 文档写入

  1. 当一个文档被索引时,它首先会被写入一个 内存缓冲区
  2. 当缓冲区满时,数据会被刷新到磁盘上,创建一个新的段。
  3. 这个新的段会包含文档的倒排索引和其他相关数据。
Untitled diagram-2024-11-13-073246.png

5.2 更新与删除

  1. 更新操作实际上是通过删除旧文档和插入新文档来实现的。
  2. 被标记为删除的文档会保留在原来的段中,直到段合并时才会被清除。
Untitled diagram-2024-11-13-073515.png

5.3 段合并

  1. 多个小段会随着时间的推移被合并为更大的段。
  2. 合并操作会移除被标记为删除的文档,并优化索引的结构。

总结

段(Segment)是 Elasticsearch 存储和索引数据的基本单元,而段合并(Segment Merge)是优化查询性能和存储空间的关键机制。理解段和段合并的工作原理,能够帮助你更好地管理 Elasticsearch 的存储和优化查询性能。在实际使用中,通过合理配置段合并策略,可以进一步提高 Elasticsearch 集群的效率和稳定性。

通过本文的讲解,你应该对 Elasticsearch 中的核心操作有了更深入的理解,希望你能结合实际业务需求,优化你的索引策略,提升性能和存储利用率。


参考资料