对elasticsearch持久化变更的一点理解

refresh–可搜索但还未持久化

数据写到一个新的segment 实现了1s(默认)的实时搜索。

fsync --持久化

提交(Commiting)一个新的段到磁盘需要一个 fsync 来确保段被物理性地写入磁盘。

flush --持久化

所有在内存缓冲区的文档都被写入一个新的段,生成一个新的提交点。这个执行一个提交并且截断 translog 的行为在 Elasticsearch 被称作一次 flush 。 分片每30分钟被自动刷新(flush),或者在 translog 太大的时候也会刷新。 — 暂时不用管这段定义。

为了ES数据的可靠–持久化

ES通过 refresh数据到segment 实现了1s(默认)的实时搜索,
也想要保证操作(插入、更新、删除)不丢失。但是fsync把数据刷新到磁盘太耗资源。于是决定定时(默认30分钟)刷新(flush)到磁盘。这里让我想到了redis的RDB 快照。
新问题出来了,30分钟才持久化一次,那么两次持久化之间(30分钟)的数据丢失了怎么办?
于是引入了 translog,在操作被refresh到segment之前已经先进入了translog。当重启ES后, 会恢复到最近的一个提交点后,再重放translog里面的操作,保证提交点生成之后的数据操作。但是translog本身还不在磁盘中,重启也会导致translog丢失。

translog持久化

对于一些大容量的偶尔丢失几秒数据问题也并不严重的集群,使用异步的 fsync 还是比较有益的。

所以让translog 5s刷新一次到磁盘。

PUT /my_index/_settings { "index.translog.durability": "async", "index.translog.sync_interval": "5s" }

Redis的AOF 不也是这样吗:AOF everysec 每秒刷一次到磁盘。
引用下别人的图片方便理解:
引用来自网络的图片

总结

redis两种持久化机制:
a.执行操作(对照es的refresh到segment阶段),然后定时(或一定操作次数后)RDB生成快照。
b.执行操作并记录操作日志(AOF),默认 1s异步追加到日志文件中(持久化操作日志,对照es的index.translog.sync_interval:5s)。

ES:
将 RDB 与AOF结合了起来:记录操作日志translog到内存,然后执行操作到内存(用户可正常查询了)。定时持久化translog(a),定时生成提交点(b),删除translog。

ps:写着写着感觉没写些啥, 就是抄了官网。之前读文档感觉懂了,但是事后一点儿都想不起来。 今天跟群友讨论突然发现ES这种持久化机制跟Redis持久化非常像,故写下来帮助自己理解。
ps:MySQL也是这样做的,参考《MySQL技术内幕 innodb存储引擎》7.2.1 redo章节。

参考

持久化变更
elasticsearch中 refresh 和flush区别

posted @ 2019-12-14 22:05  thewindkee  阅读(1374)  评论(0编辑  收藏  举报