ES 的近实时搜索 filesystem cache 与 事务日志 Translog 数据恢复

ES 的近实时搜索 filesystem cache 与 事务日志 Translog 数据恢复,第1张

ES 的近实时搜索 filesystem cache 与 事务日志 Translog 数据恢复 近实时搜索的 filesystem cache 与 事务日志 Translog

本文主要想讨论一下,Elasticsearch 的近实时搜索,而在聊这个之前,先普及一下 ES 的数据和索引存储

文件和索引数据概述

Elasticsearch 是一个分布式的文档存储。Elasticsearch 不是采用 通常数据库 的 列式数据行 存储的存储形式。

而是存储 已序列化的 JSON 结构 的复杂数据结构。当集群中有多个 Elasticsearch 节点时,数据将分布在整个集群中,并且每个节点都可以对其进行快速访问。

ES 在存储文档后将可以近乎实时地索引并可以完全搜索 – 1 秒内。

Elasticsearch 使用了一种称之为 倒排索引 的索引结构(倒排索引是词典 ( Term Dictionary ) 到文档列表 ( Postings List ) 的映射关系),该索引结构可以支持非常快速的全文搜索,倒排索引列出了任何文档中出现的不同的单词,并标识了每个单词出现的所有文档。

索引 (index) 可以认为是文档的优化集合,文档 (document) 是字段的集合,字段 (field) 是包含数据的键值对。

默认情况下,Elasticsearch 索引每个字段的所有数据,并且每个字段都有专用的优化数据结构。如文本字段存储在倒排索引中,而数字类型和地理字段存储在 BKD 树中

近实时的搜索 名词解释

Commit point 提交点 标识提交到磁盘中的 segment

per-segment search 每段搜索 segment 类似于 inverted index 倒排索引 Elasticsearch 所基于的 Java 库 Lucene 引入了每段搜索的概念

Lucene 中的 index 索引: 多个 segment 段的集合 + 一个 commit point 提交点

In-memory buffer

内存缓冲区,当你写一条数据时会先写入 memory buffer 同时写入 translog (后文会提)。此时的写入并不能搜索,直到 buffer 满,或者到达周期触发 refresh ,此时会将 memory buffer 中改动移到 文件系统缓存 即 filesystem cache ,此时可被搜索但仍在内存中。

filesystem cache:

在 Elasticsearch 和 磁盘中间的是 文件系统缓存 filesystem cache。新的 segment 会写入到 filesystem cache (这是一个轻量级 *** 作),然后才 刷新 flush 到磁盘 (这个 *** 作很昂贵),但是 segment 在提交到缓存时就可以被打开和写入了,和其他写入磁盘的文档一样。

Luence 允许打开和写入新的段,使他们包含的文档对搜索可见,而无需执行完整的提交。这是一个比提交到磁盘更轻量级的过程,可以经常执行且不影响性能。

在 commit 提交(写入磁盘)之后,新的 segment 将被添加到 commit point 并且会清空 In-memory buffer

图 1. 内存缓冲区中有新文档的 Lucene 索引

图 2. 将缓冲区内容写入可搜索但尚未提交的段

在 ES 中 这个写入和打开新的 segment 的过程称之为 刷新 refresh。刷新可以使得自上次刷新以来所有的 *** 作都可以用于搜索。

以下方式可以触发刷新

等待刷新间隔设置?refresh选项使用Refresh API显式完成刷新 ( POST _refresh)

默认情况下 Elasticsearch 每秒刷新,但仅在 30 秒内收到一个或者多个请求的索引上。这也就是为什么是 近乎实时的搜索

引出问题:

Elasticsearch 虽然引入 filesystem cache 加快了可实时搜索的速度,但也引入了一个问题,数据不是实时写入磁盘的,这就会导致在 commit 之前,如果服务出现问题 filesystem cache 中的数据会丢失的问题。为此引入了 Translog

Translog 事务日志

Lucene 提交是一个昂贵的 *** 作,无法对每个单独的 *** 作单独执行,所以引入了 Translog 事务日志,每个分片副本将 *** 作记录写入 Translog。所有索引的写入和删除 *** 作在 Luence 内部处理之后确认之前被写入 Translog。这样如果发生崩溃,则在分片恢复时已确认但未提交写入磁盘的数据将从 Translog 中进行恢复。

Elasticsearch 的 flush *** 作会执行 commit 提交 和 新的 Translog 生成,刷新是后台自动执行的,以确保 Translog 不会太大而使得恢复需要相当长的时间进行重放。

Translog 的持久化设置

Translog 仅在 fsync 编辑提交时才会持久化到磁盘。

index.translog.durability 用于控制持久化

request (默认的): fsync 在每次请求后都提交。如果发生故障,所有确认的写入都已提交到磁盘。

async:fsync并在后台提交每个sync_interval. 如果发生故障,自上次自动提交以来所有确认的写入都将被丢弃。

index.translog.sync_interval

无论写入 *** 作如何,translog 多久被fsync写入磁盘并提交一次。默认为5s. 小于的值100ms是不允许的。

index.translog.flush_threshold_size

Translog 存储所有尚未提交的 *** 作,如果这中间发生故障,则需要通过 Translog 进行重放以便恢复数据。然而如果如果 *** 作过多会导致重放时间过长,此配置用于控制存储 *** 作的大小,默认为 512 M ,如果达到该配置数值,则会进行 flush

总结 Flush

flush *** 作会进行 commit,并清除 translog。

在新版的 ES 中仅当 translog 达到阈值(默认 512 M 可配置)会进行 flush ,即仅此时会将 filesystem cache 中的改动持久化到磁盘。

当然你也可以手动调用强制刷新

参考官方文档:
index-modules-translog

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5718003.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存