重生之我们在ES顶端相遇第16 章 - Lucene 写入流程

发布于:2024-10-12 ⋅ 阅读:(122) ⋅ 点赞:(0)

前言

上一章我们介绍了倒排索引的数据结构。
本章我们将深入介绍 Lucene 写入流程。
该知识点在面试中比较常问,也是理解 ES 必须掌握的知识点。

写入流程图

在第 14 章,我在介绍 coordinating node 时,画了 coordinating node 的工作流图,但是只画到了 data node
那么当数据到达 data node 后,ES 是如何将数据写入的呢?

我们来看一个 ES 比较完整的写入流程图
在这里插入图片描述

图中标红的地方,就是我们要详细讲解的内容。

从图中,我们可以知道:

  • 1 个 Data Node 可以有非常多的 Lucene 实例
  • 1 个分片就是一个 Lucene 实例(ES 是基于 Apache Lucene 开发的)
  • 1 个 Segement 就是一个倒排索引

refresh

数据写入时,先写入到内存,此时这部分数据无法被检索。Refresh 后, 数据就能被检索。这也是为什么 ES 被称为 近实时查询 的原因。

当发生 Refresh 时,数据会被写入操作系统 file cache,并清空 Memory buffer

这里,我们不禁要产生疑问了:

  1. 什么时候触发 Refresh
  2. Refresh 只是将数据写入 file cache,但 file cache 在操作系统掉电或崩溃后,数据会丢失的,这怎么办?
Refresh 触发时机
  1. Memory Buffer
  2. refresh_interval(创建索引时可以指定) 时间到
Translog

为了避免 file cache 掉电或崩溃后数据丢失。ES 在触发 Refresh 时,同时还会写入 translog,用于恢复未落盘的数据。

translog 具有以下几个特点:

  1. 顺序写入,写入速度快
  2. 每个分片都有对应的 translog
  3. translog 默认每次索引写入时落盘
  4. 触发 flush 后,translog 会被清空(segment 都落盘了,旧的 translog 肯定没用了)

Flush

Flush 阶段的作用是执行 fsync, 将 segment 落盘。

ES 默认每隔 30 分钟执行 1 次 Flush 操作,执行内容如下:

  1. 执行 Refresh
  2. 清空 translog

Merge

你可能也注意到了,每次写入都不会去修改旧的 segment,而是生成新的 segment(segment 不可变)。也因此,segment 是一个不断增多的过程。
segment 增多的时候,ES 查询性能会下降,因此需要定时的合并 segment

Merge 是 ES 内部自动处理的。当然我们可以强制让 ES 执行 Merge,也可以控制 Merge 时的并发线程。

  • 强制 Merge
    POST /{your-index}/_forcemerge

  • 控制并发线程
    index.merge.scheduler.max_thread_count。该配置默认值为:Math.max(1, Math.min(4, <<node.processors>> / 2))


网站公告

今日签到

点亮在社区的每一天
去签到