Elasticsearch 的 translog
在 Elasticsearch(ES)中,translog(事务日志) 是保障数据持久性(Durability)和故障恢复能力的核心组件
本质是一份追加写的日志文件,用于记录所有对 ES 索引的 “写操作”(如索引创建、文档新增 / 修改 / 删除)
相当于 ES 数据的 “安全备份日志”
translog 的核心作用:解决 “持久性” 与 “性能” 的矛盾
ES 的底层存储依赖 Lucene(读作:鹿森) 索引(ES 索引由多个 Lucene 分片组成),而 Lucene 写入数据时,为了平衡性能,会先将数据写入内存中的 Lucene 缓冲(In-Memory Buffer),而非直接刷盘(磁盘 IO 性能远低于内存)
内存数据断电易失,此时 translog 就是 “兜底保障”:
确保数据持久性(Durability)
所有写操作(如 index/update/delete)执行时,ES 会先将操作记录追加写入 translog(顺序写,性能高),再更新 Lucene 内存缓冲
只有当 translog 成功写入磁盘(默认配置下,translog 会实时刷盘到操作系统缓存,默认 5 秒后强制刷到物理磁盘),ES 才会向客户端返回 “操作成功” 的响应
即使此时 Lucene 内存缓冲的数据未刷盘(未生成 Lucene 分段文件),若 ES 进程崩溃或服务器断电,重启后可通过 translog 恢复未刷盘的数据,避免丢失
支持故障恢复(Recovery)
当 ES 节点重启、分片迁移(如集群扩容 / 缩容)或主分片故障切换时,从分片(Replica Shard)需要与主分片(Primary Shard)数据保持一致,此时 translog 是关键:
- 主分片会将 “从分片未同步的 translog 记录” 发送给从分片,从分片通过重放这些记录,快速追上主分片的数据状态
- 节点重启时,ES 会先加载磁盘上的 Lucene 分段文件(基础数据),再重放 translog 中 “分段文件生成后未刷盘的操作”,恢复到崩溃前的最新数据状态
优化 Lucene 刷盘性能
Lucene 内存缓冲的数据需要定期 “刷盘”(即生成不可变的 Lucene 分段文件),但频繁刷盘会导致大量磁盘随机 IO,性能低下;
translog 允许 Lucene 缓冲积累一定数据后再批量刷盘(默认每隔 1 秒自动刷盘,或缓冲满时触发),而 translog 本身通过 “顺序写” 承担了 “实时持久化” 的责任,兼顾了性能与安全性。
translog 的工作流程:从写入到清理
translog 的生命周期与 Lucene 刷盘(Flush)操作强关联,整体流程如下:
写操作触发
客户端发送写请求(如新增文档),ES 主分片先将操作记录追加写入 translog(顺序写,速度快),再更新 Lucene 内存缓冲
translog 刷盘
实时刷盘到操作系统缓存:
默认情况下,translog 写入后会立即刷到操作系统缓存(OS Cache),确保进程崩溃时数据不丢失(操作系统会保障缓存数据的持久性)
定期刷到物理磁盘:
ES 会每隔 index.translog.durability 配置的时间(默认 5 秒),将操作系统缓存中的 translog 强制刷到物理磁盘,进一步降低断电丢失风险
Lucene 刷盘(Flush)与 translog 清理:
当 Lucene 内存缓冲满(默认达到 512MB)或达到定时周期(默认 1 秒),ES 会触发 Flush 操作:
将内存缓冲的数据刷盘生成 Lucene 分段文件(不可变)
Flush 完成后,translog 中 “已刷盘到 Lucene 分段的操作记录” 就失去了作用(数据已被 Lucene 持久化)
ES 会自动清理这些旧记录,避免 translog 文件无限膨胀
translog 滚动(Rollover):
当 translog 文件达到一定大小(默认 512MB)或存在时间过长,ES 会创建新的 translog 文件,旧文件保留用于故障恢复,直到确认数据已完全持久化到 Lucene 分段后才会删除。
translog 的关键配置:平衡性能与持久性
ES 允许通过配置调整 translog 的行为,核心配置项在索引级别(可通过 PUT /索引名/_settings 修改),常见配置如下:
配置项 默认值 含义说明
index.translog.durability REQUEST 控制 translog 刷盘时机,决定 “持久性级别”:
- REQUEST:每次写请求后,强制将 translog 刷到操作系统缓存(默认,安全性高,性能略低)
- ASYNC:每隔 5 秒批量刷盘(性能高,但可能丢失 5 秒内的数据,适合非核心数据)
index.translog.sync_interval 5s 当 durability=ASYNC 时,translog 批量刷盘的时间间隔(最小 100ms)
index.translog.flush_threshold_size 512mb 触发 Flush 操作的 translog 大小阈值:当 translog 文件达到该大小,会强制触发 Flush,清理旧记录
index.translog.retention.size 512mb 保留的 translog 总大小上限:超过后会删除最旧的 translog 文件(需确保不小于 flush_threshold_size)
index.translog.retention.age 12h 保留的 translog 最大存在时间:超过 12 小时的 translog 文件会被删除(即使未达到大小阈值)
translog 与 Lucene 的关系:相辅相成
很多人会混淆 translog 和 Lucene 分段文件:
对比维度 translog Lucene 分段文件(Segment)
数据形式 追加写的日志(记录操作,如 “新增doc ID=1”) 不可变的倒排索引文件(存储完整文档数据和索引结构)
读写特性 顺序写(快),支持读(用于恢复) 随机读(快,支持查询),不可写(生成后无法修改)
核心作用 实时持久化、故障恢复 提供高效查询、长期数据存储
生命周期 随 Flush 清理,短期存在 长期存在,定期合并(减少分段数量)
translog 是 “临时保障”,确保 Lucene 缓冲数据在刷盘前不丢失
Lucene 分段是 “长期存储”,一旦数据刷盘到分段,translog 中的对应记录就可清理
两者共同保障 ES 的 “高性能写入” 和 “高可靠性存储”
注意事项:避免 translog 相关问题
避免 translog 过大
若 translog 文件过大(如超过 10GB),会导致 Flush 操作耗时过长(需清理大量旧记录),甚至节点重启时恢复时间变长(需重放大量 translog)。建议合理设置 flush_threshold_size(如 512MB~2GB)
谨慎选择 durability=ASYNC
虽然 ASYNC 能提升写入性能,但极端情况下(如服务器断电)会丢失 5 秒内的数据,仅适合 “非核心数据”(如日志、监控数据)
核心业务数据建议使用默认的 REQUEST 模式
translog 损坏的处理
若 translog 文件损坏(如磁盘错误),ES 无法通过它恢复数据,可能导致分片无法启动。
此时需通过 POST /索引名/_clone 克隆索引(自动跳过损坏的 translog),或从备份恢复数据
总结
translog 是 ES 保障数据持久性的 “核心保险”
通过 “顺序写日志” 的方式,解决 Lucene 内存缓冲 “性能高但易失” 的问题,同时支持故障恢复和分片同步
理解 translog 的工作机制和配置,能帮助开发者在 “写入性能” 和 “数据安全性” 之间找到平衡,优化 ES 集群的稳定性