前言

Elasticsearch 在处理文档变更的时候,首先会把变更记录在索引缓冲区里,然后每隔 1s 将索引缓冲区刷新到文件系统缓存,存在于文件系统缓存中的变更会定时 fsync 到磁,默认情况下, Elasticsearch 每 30m 进行一次 flush,此时会 fsync 持久化文档到磁盘,文档数据持久化到磁盘才算不会丢失了。

在未持久化到磁盘之前如果发生了意外情况可能会导致数据丢失,比如:Elasticsearch 宕机(索引缓冲区未刷新的数据会丢失),机房断电导致操作系统重启(文件系统缓存中的数据会丢失)。

事务日志

简介&作用

为了避免数据丢失,Elasticsearch 在数据的变更提交过程中增加了事务日志(Translog),事务日志采用追加写的方式,是磁盘上一块区域内的顺序I/O,避免了随机 I/O 需要在磁盘的多个地方移动磁头,事务日志的写入速度相对来说要快很多。

一个文档被索引后,会添加到内存缓冲区,同时记录到 Translog 中。
image.png

内存缓冲区每隔 1s 会 refresh 一次,refresh 完成后内存缓冲区清空,Translog 不清空。
image.png

默认情况下,在每次写请求完成之后(e.g. index, delete, update, bulk)。Translog 在主分片和每个副本分片上 request 成功编辑并提交后(此时 Translog 持久化到磁盘),才会向客户端报告索引、删除、更新或批量请求的成功。这意味着在整个写请求被 fsync 到主分片和复制分片的 Translog 之前,客户端不会得到一个 200 OK 响应。这保障了在默认情况下,如果客户端收到 200 OK 的响应,数据就持久化到磁盘了,不会丢失。

异步 fsync

每次写请求后都执行一个 fsync 会带来一些性能损失,尽管实践表明这种损失相对较小(特别是 bulk 导入,它在一次请求中平摊了大量文档的开销)。

对于一些写入频繁且容量大偶尔丢失几秒数据问题也并不严重的集群,使用异步的 fsync 可以提高写入性能。比如,写入的数据被缓存到内存中(Translog disk page chache),再每 5s 执行一次 fsync。这个可以通过设置 durability 参数为 async 来启用:

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

这个选项可以针对索引单独设置,并且可以动态进行修改。如果决定使用异步 Translog 的话,就需要能接受在发生 crash 时,丢失掉 sync_interval 时间段的数据也无所谓。

总结

事务日志提供了一种持久化保障,意外情况可能会发生,期间数据可能会丢失,但是能够从事务日志中进行恢复其实已经几近做到了数据不丢失。大多数分布式应用中,数据不丢失保障采用的解决方案也都如此。

参考

https://www.elastic.co/guide/...


阿白
6 声望0 粉丝