赞
踩
作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
本章,我们来看下Elasticsearch的持久化原理,也就是数据在底层究竟是如何写入到磁盘上的。开始之前,先来了解一个基本概念—— Segment 。
我们知道,在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数据被写入磁盘会经历以下几个过程:
首先,document会被写入 in-memory buffer 中,所谓 in-memory buffer 其实就是应用内存。同时,document数据会被写入 translog 日志文件。
每隔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的时间间隔。
上述过程中,segment file一直存在于os cache中,如果发生宕机,cache中的数据就会丢失。所以需要有一种机制能将os cache中的数据写入磁盘文件。这一过程在Elasticsearch中就叫做 flush 。
在refresh的过程中,os cache中的segment file会越来越多(每次refresh都会创建一个新的segment file), translog 日志文件也会越来越大。当translog大到一定程度的时候,就会触发 flush 操作:
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文件,但是这会导致写性能、吞吐量严重下降。
由于每refresh一次,就会os cache中产生一个新的segment file,所以随着segment file越来越多,搜索的性能会降低。此时,Elasticsearch会定期执行 merge 操作。
每次merge时,ES会选择一些相似大小的segment进行合并,同时会将那些标识为deleted
的document物理删除掉。合并后新的segment file会被写入磁盘,同时会新建commit point文件,里面标识着所有合并后新的segment file。
本章,我介绍了Elasticsearch的持久化原理,核心就是refresh
、flush
、merge
这三个操作。目前很多开源分布式框架都采用了这种数据持久化的思路。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。