1. 概念
我们知道,Elasticsearch(ES) 的底层存储引擎是 Lucene,ES 调用 Lucene 的接口进行 CRUD,写入 Lucene 的数据首先是缓存在内存中,只有 commit 后才持久化并可以搜索。commit 是一个开销比较大的操作,因此不可能每次写入或删除都调用 commit,为了保证数据的可靠性,ES 引入了 Translog。ES 每次调用 Lucene 的接口写入或删除数据后,都会将操作日志记录到 Translog 中防止意外断电或程序奔溃导致数据丢失。如下:
2. 设置
-
同步间隔(index.translog.sync_interval)
Translog 的日志每次都会写入到操作系统的缓存中,只有执行 fsync 刷盘后才是安全的。因此 ES 会每隔一段时间执行 fsync 刷盘。默认时间间隔是 5s,最低不能低于 500ms。注:改参数只针对异步落盘方式才生效。 -
刷盘方式(index.translog.durability)
Translog 的刷盘方式有两种:同步(request)和异步(async)
ES 默认使用的是 request,即每次写入、更新、删除操作后立刻执行 fsync 落盘。
如果使用异步的方式,则根据同步间隔周期性的刷盘。
两种方式各有千秋,同步刷盘具备更强数据可靠性保障,但同时带来更高的 IO 开销,性能更低。异步刷盘牺牲了一定的可靠性保障,但是降低了 IO 的开销,性能更佳,因此需要根据不同的场景需求选择合适的方式。 -
大小阈值 (index.translog.flush_threshold_size)
我们不可能让 translog 的大小无限增长。translog 的大小过大会带来如下问题:占用磁盘空间;节点恢复需要同步 translog 回放日志,如果太大会导致恢复时间过长。因此,需要设定一个阈值,当日志量达到该阈值时,触发 flush,生成一个新的提交点,提交点之前的日志便可以删除了(具体能否删除还需结合日志的保留时长和保留大小而定)。 -
日志保留大小(index.translog.retention.size)
该设置项控制 translog 保留的大小。translog 保留的目的是为了在副本故障恢复时,提高恢复速度(主保留 translog,从恢复时,只需将 global checkpoint 后的日志发送给从就 ok 了) -
日志保留时长(index.translog.retention.age)
同上,满足任一条件即可 -
日志 generation 阈值大小(index.translog.generation_threshold_size)
为了避免 translog 越来越大,增加恢复的时间。在 translog 达到阈值时,会执行 flush,触发 lucene commit,并滚动 translog 生成新的文件,当前 generation 前的操作数据都会提交到 lucene 持久化,恢复时,只需恢复当前 translog 中的操作即可。