👉 简答(适合快速面试回答):
Elasticsearch 在接收到写入请求后,先写入内存缓冲区(translog + 内存索引),然后异步刷新到磁盘段文件(Lucene),默认每隔 1 秒自动
refresh
。只有在flush
或 translog fsync 后,数据才算真正持久化。
✅ 写入过程详解(专业面试用)
当你向 Elasticsearch 发送一个写入请求(如 index
、update
、delete
),会经历以下步骤:
1. 写入内存 buffer + translog
-
写入数据先被放入内存中的段缓存 buffer
-
同时写入 translog(事务日志,WAL 类似),是顺序磁盘写
-
translog 是为了 防止宕机时数据丢失,但它也需要定期 fsync 才真正写入磁盘
2. 异步 refresh
→ 可搜索
-
默认每 1 秒执行一次
refresh
,将内存 buffer 中的数据刷新成 Lucene 的 segment(不可变磁盘结构) -
这个时候数据才变得 对搜索可见
📌注意:refresh
≠ flush
,只是为了查询而刷新,不是持久化操作
3. flush
操作 → 真正持久化
-
flush
会将当前内存 buffer 清空 + translog 清除 + segment 写入磁盘 -
默认非自动,但也可以定期做
-
当发生以下情况时,会自动触发
flush
:-
translog 太大
-
手动调用 API(
POST /index/_flush
) -
正常节点关闭前会 flush
-
Elasticsearch 重启时,未 flush 的 translog 会被 replay
-
✅ 写入关键参数
参数 | 默认值 | 说明 |
---|---|---|
refresh_interval | 1s | 多久自动刷新一次,影响数据搜索可见性 |
translog.flush_threshold_size | 512mb | translog 超过此大小自动触发 flush |
number_of_replicas | 1 | 写入时会同步到副本,保障高可用 |
✅ 回答模板(进阶型)【用于面试高分回答】
Elasticsearch 并不是每次写入立即就落磁盘,而是采用类似 Write-Ahead-Log 的机制:
写入数据首先进入内存缓存 + translog,保证高性能;每 1 秒 refresh 一次,让数据对搜索可见;而真正持久化是在 flush 过程中完成的。
我们实际在使用中,会特别关注 refresh 和 flush 的间隔、translog 的大小阈值以及 ES 异常重启后的恢复机制,避免因 refresh 未及时、translog 丢失导致的数据不一致问题。
✅ 加分场景补充:如何保障 ES 写入不丢数据?
风险场景 | 保障方案 |
---|---|
写入后宕机,refresh 未发生 | 配置合理的 refresh + flush,重要数据可强制 refresh |
写入后 translog 未 fsync | 设置 durability: request 保证 fsync 写盘 |
Bulk 写入失败部分未监控 | 捕捉 BulkResponse 中的错误项进行重试 |
Kafka 消费者处理失败未补偿 | 接入死信队列(DLQ) + 数据补偿任务 |