理解 Elasticsearch translog、refresh、flush 原理

烽火连三月,家书抵万金。

1 前言

最近在工作中接触到了 Elasticsearch 数据存储,对其近实时的查询很感兴趣,于是自己研究了一番其工作原理。在本文中将从 Elasticsearch 的索引工作机制来剖析 translogrefreshflush 在数据存储中的作用和特点。

2 基本概念

我们都知道 ES 的存储基本单元为 shard, 是基于 Lucence 做的索引, 一个 Index 中有多个 shard, 每个 Index 是由多个 Segment 组成的。每个 Segment 都是一些倒排索引的集合,每次创建一个文档 Document ,都会归属到一个新的 Segment, 而不是去修改原来的 Segment。每次文档的删除只是将文档添加删除标记而不是真正的物理删除。每当修改文档时,也是将旧文档标识为删除,新建一个文档存储修改后的内容,删除的数据在 .del 文件中会有标记在查询数据时会过滤删除的数据。

ESindex 是一个逻辑的抽象概念,ES 会固定时间生成一个新的 Segment 文件,当 Segment 文件过多时会进行合并 merge 操作, 合并时会将标识为删除的文档物理删除。

3 参数解析

refresh 是指在 ES 中,将缓存中的文档写入 segment,并打开 segment 使之可以被搜索的过程。

ini 复制代码
# refresh 的刷新频率
# 近实时的操作就在于此,默认数据写入 segment 到数据可查询的间隔
index.refresh_interval=1s

commit point 这个是和数据库事务操作类似的,也是为了数据的安全,每次索引变更都会立即刷盘,这个动作会将 Segment 进行合并并写盘,保证内存中的数据尽量不丢失。刷盘 flush 是很重的io 操作,为了保证机器的性能并保证搜索的近实时性,通常 flush 操作不会那么频繁。

flush的概念: ES 间隔 30 min 或者数据量达到 512MB 时,会将内存 buffer 数据全部写入新的 segment 中,内存 buffer 被清空,一个 commit point 被写入磁盘,并将 filesystem cache 中的数据通过 fsync 刷入磁盘,同时清空 translog 日志文件。

fsync fsync 是 linux 系统的调用函数,是将内存 buffer 中的数据存储到文件系统中, 这里是将 filesystem cache 中的所有 segment 刷新到磁盘的操作。

translog的概念:translog 的概念和 mysql 数据库的两次写类似,都是采用了 WAL (write ahead of log)技术, 提供所有还没有刷到磁盘的操作的一个持久化记录。

ini 复制代码
# translog 的刷新频率
index.translog.sync_interval=5s
# 同步方式:异步、同步、每次请求都处理
index.translog.durability=async|fsync|request
# translog 的默认大小
index.translog.flush_threshold_size=512MB

ES 启动时,它会从磁盘中使用最后一个提交点去恢复已知的 Segment, 并且重做 translog 中所有的变更操作。为了防止 ES 宕机所造成的的数据丢失、保证数据的可靠性。ES 的每次操作不仅要写入内存 buffer , 还会被写入到 translog 文件,每个 shard 都对应一个 translog , translog 间隔 5s 会异步执行或者每个请求完成后执行一次 fsync 操作,将 translog 从缓存写入磁盘,这样的操作比较耗时,如果对数据实时性要求不高可以改为 async 方式,否则节点宕机会有 5s 的数据丢失。

4 总结

在本文中,主要介绍了 ES 的近实时操作的实现原理,介绍了 flushrefreshtranslog 的基本概念和实现,并且介绍了对应的参数配置。 ES 在搜索方面的使用十分广泛,特别是在非结构化数据的场景。在项目中,如果是结构化数据可以采用 ES 或者 云数据库来解决,两种的性能不相上下,但是云数据库成本相对更低,但是对于非结构化的数据搜索,特别是日志搜索系统,ES 的作用会更大一点,在实际开发中要结合应用场景来选择对应的存储设备。

相关推荐
理想青年宁兴星11 分钟前
【SpringBoot】Java中isEmpty使用不当报错空指针
java·spring boot·后端
我要成为Java糕手31 分钟前
支付相关—支付宝小程序非同一主体下多商户进行收款
后端
arnold661 小时前
ElasticSearch 分布式部署
elasticsearch
阿泽不想掉光头发1 小时前
C#实现调用DLL 套壳读卡程序(桌面程序开发)
java·开发语言·后端·websocket·http·c#
峰子20122 小时前
Go语言实现守护进程的挑战
开发语言·后端·面试·架构·golang·go
小马爱打代码2 小时前
Spring Boot项目开发常见问题及解决方案(下)
java·spring boot·后端
绝无仅有3 小时前
gozero项目日志Prometheus的配置与实战
后端·面试·架构
Q_19284999063 小时前
基于Spring Boot的工商局商家管理系统
java·spring boot·后端
web136885658713 小时前
rust教程 第一章 —— 初识rust
开发语言·后端·rust
songroom3 小时前
Rust : tokio中select!
开发语言·后端·rust