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章节。