分布式进阶(九)——分布式框架之高性能:ElasticSearch数据持久化

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

本章,我们来看下Elasticsearch的持久化原理,也就是数据在底层究竟是如何写入到磁盘上的。开始之前,先来了解一个基本概念—— Segment 。

一、Segment File

我们知道,在Elasticsearch中创建一个index索引时,需要指定shard分片,一个shard分片在底层其实是一个Lucene索引,它 由若干个segment文件和对应的commit point(提交点文件)构成 。

segment文件可以理解成底层存储document数据的文件,ES进行检索时最终是从它里面检索出数据的;而commit point文件可以理解成一个保存了若干segment信息的列表,它标识着这个commit point前所有旧的segment file文件。

举个例子,当Elasticsearch创建commit point文件时,会已有一些segment文件是已经存在的,那commit point就保存着这些旧的segment文件的信息:

二、写入流程

一条document数据被写入磁盘会经历以下几个过程:

1.1 write

首先,document会被写入 in-memory buffer 中,所谓 in-memory buffer 其实就是应用内存。同时,document数据会被写入 translog 日志文件。

1.2 refresh

每隔1秒,Elasticsearch会执行一次 refresh 操作:将buffer中的数据refresh到filesystem cache中的一个新segment file中。filesystem cache其实就是os cache,性能非常好。注意,此时的segment file仅仅是存在于os cache中的缓存数据,并不存在于磁盘上。

refresh操作完成后,buffer会被清空。另外,如果buffer满了也会执行refresh。 当数据进入filesystem cache后,其实就可以被检索到了 。

为什么说Elasticsearch是准实时(NRT,near real-time)的?因为默认每隔1秒refresh一次,所以写入的数据1秒之后才能被检索到。可以通过index的index.refresh_interval参数配置refresh的时间间隔。

1.3 flush

上述过程中,segment file一直存在于os cache中,如果发生宕机,cache中的数据就会丢失。所以需要有一种机制能将os cache中的数据写入磁盘文件。这一过程在Elasticsearch中就叫做 flush 。

在refresh的过程中,os cache中的segment file会越来越多(每次refresh都会创建一个新的segment file), translog 日志文件也会越来越大。当translog大到一定程度的时候,就会触发 flush 操作:

  1. flush的第一步,将buffer中的现有数据refresh到os cache中,清空buffer;
  2. 在磁盘上写入一个commit point文件,里面标识着这个commit point前os cache中的所有旧segment file文件数据;
  3. 强行将os cache中的所有数据fsync到磁盘文件中去;
  4. 最后将translog清空,因为此时里面记录的数据此时都已经被fsync到磁盘了。

默认每隔30分钟会自动执行一次 flush 操作,但是如果translog过大,也会提前触发。

这里来思考下,translog日志文件的作用是什么?

在执行flush操作之前,数据要么是停留在buffer中,要么是停留在os cache中,此时一旦这台机器宕机,数据就全丢了。所以,需要将数据写入到一个专门的日志文件中,此时即使机器宕机了,再次重启时,Elasticsearch会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。

另外,translog中的数据,本身也是先写入os cache,然后默认每隔5秒刷一次到磁盘中。所以默认情况下,即使有translog保证可用性,也可能丢失5s的数据。此时数据仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失这5秒钟的数据。

如果你希望一定不能丢失数据的话,可以设置index的index.translog.durability参数,使每次写入一条数据,都是写入buffer,同时fsync写入磁盘上的translog文件,但是这会导致写性能、吞吐量严重下降。

1.4 merge

由于每refresh一次,就会os cache中产生一个新的segment file,所以随着segment file越来越多,搜索的性能会降低。此时,Elasticsearch会定期执行 merge 操作。

每次merge时,ES会选择一些相似大小的segment进行合并,同时会将那些标识为deleted的document物理删除掉。合并后新的segment file会被写入磁盘,同时会新建commit point文件,里面标识着所有合并后新的segment file。

三、总结

本章,我介绍了Elasticsearch的持久化原理,核心就是refreshflushmerge这三个操作。目前很多开源分布式框架都采用了这种数据持久化的思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值