ES如何保障数据不丢失

前言 Elasticsearch 在处理文档变更的时候,首先会把变更记录在索引缓冲区里,然后每隔 1s 将索引缓冲区刷新到文件系统缓存,存在于文件系统缓存中的变更会定时 fsync 到磁盘,文档变更持久化到了硬盘才算不会丢失了。
在未持久化到磁盘之前如果发生了意外情况可能会导致数据丢失,比如:Elasticsearch 宕机(索引缓冲区未刷新的变更会丢失),机房断电导致操作系统重启(文件系统缓存中的变更会丢失)。
事务日志 简介&作用
Elasticsearch 在数据的变更提交过程中增加了事务日志(Translog),采用追加写的方式。事务日志是磁盘上一块区域内的顺序I/O,避免了随机 I/O 需要在磁盘的多个地方移动磁头,事务日志的方式相对来说要快很多。
一个文档被索引后,会添加到内存缓冲区,同时记录到事务日志。
ES如何保障数据不丢失
文章图片

内存缓冲区 refresh 后,事务日志不清空。
ES如何保障数据不丢失
文章图片

Elasticsearch 索引的每个分片都存在一个事务日志,事务日志记录完成后才会给客户端返回成功。这就意味着,只要客户端接到成功响应,文档的变更就已经持久化到磁盘了,体现在事务日志里。
事务日志提供所有还没有被刷到磁盘的操作的一个持久化纪录。当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点(Commit point)去恢复已知的段,并且会重放 Translog 中所有在最后一次提交后发生的变更操作。
安全性
在文档变更被 fsync(fsync 指的是持久化文档变更到事务日志)到磁盘前,变更的文档在重启之后就会丢失。默认 Translog 是每 5s 被 fsync 刷新到硬盘,或者在每次写请求完成之后执行(e.g. index, delete, update, bulk)。这个过程在主分片和复制分片都会发生。最终,这意味着在整个请求被 fsync 到主分片和复制分片的 Translog 之前,客户端不会得到一个 200 OK 响应。
在每次请求后都执行一个 fsync 会带来一些性能损失,尽管实践表明这种损失相对较小(特别是bulk 导入,它在一次请求中平摊了大量文档的开销)。
但是对于一些大容量的偶尔丢失几秒数据问题也并不严重的集群,使用异步的 fsync 还是比较有益的。比如,写入的数据被缓存到内存中,再每 5s 执行一次 fsync。 这个行为可以通过设置 durability 参数为 async 来启用:

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

这个选项可以针对索引单独设置,并且可以动态进行修改。如果决定使用异步 Translog 的话,就需要能接受在发生 crash 时,丢失掉 sync_interval 时间段的数据也无所谓。
总结 【ES如何保障数据不丢失】事务日志提供了一种持久化保障,意外情况可能会发生,期间数据可能会丢失,但是能够从事务日志中进行恢复其实已经几近做到了数据不丢失。大多数分布式应用中,分区数据一致性保障,数据不丢失保障采用的解决方案也都如此。

    推荐阅读