首页/数据/NoSQL 速查/refresh 与 flush 的区别
Elasticsearch89 条

refresh 与 flush 的区别

refresh 让新写入的文档进入可搜索状态(默认每秒一次),flush 把内存缓冲区与 translog 落盘并清空 translog;两者目的不同,不能互相替代。

NoSQL 速查数据更新于 2026-10-13

两件事别混为一谈

refresh 管的是可见性:把内存缓冲里新写入的文档刷成一个新的 Lucene 段,文档从此能被搜到,这正是 Elasticsearch「近实时搜索」的来源。flush 管的是持久化与恢复速度:触发一次 Lucene commit 把已刷新的段落盘,并清掉 translog 里已提交的部分。

基本信息

适用版本Elasticsearch 7.x / 8.x
refresh 默认间隔index.refresh_interval 为 1s
关闭自动刷新index.refresh_interval 设为 -1
flush 做什么Lucene commit + 清空已提交的 translog
相关 APIPOST /<index>/_refresh、POST /<index>/_flush

典型使用场景

  • 批量导入:先把 refresh_interval 设为 -1 再灌数据,结束时恢复并手动刷新一次
  • 写完立刻要能查到:单条写入用 refresh=true 或 refresh=wait_for,或写后手动 _refresh
  • 重建索引收尾:_reindex 完成后手动 _refresh,确认新索引导入结果可查
  • 存档与停写:批量任务结束后 flush,缩短后续重启时的恢复时间
  • 排查「数据写进去了却搜不到」:先看 refresh_interval 与最近一次 refresh 时间

示例

示例
POST /my-index/_refresh                  # 立即让新写入的文档可被搜索

PUT /my-index/_settings                   # 导入期先关掉自动刷新,减少小段
{ "index": { "refresh_interval": "-1" } }

POST /my-index/_bulk?refresh=false        # 批量写入不加 refresh
{ ... }

PUT /my-index/_settings                   # 导入完成后必须恢复,否则新数据永远搜不到
{ "index": { "refresh_interval": "30s" } }
POST /my-index/_refresh                   # 恢复后手动刷一次,让存量数据立即可查

POST /my-index/_flush                     # 落盘 + 清空 translog
GET /_cat/indices/my-index?v&h=index,health,docs.count,store.size

两个动作对照

动作做了什么代价
refresh内存缓冲刷成可检索段,文档变为可搜索生成小段,段越多后台合并压力越大
flushLucene commit 落盘并清空已提交 translog磁盘 I/O 上升,换来更快的重启恢复
refresh_interval控制自动 refresh 周期,默认 1s设 -1 后新文档不可搜,必须手动刷新
refresh=wait_for写入请求等待下一次 refresh 完成再返回等待上限受 refresh_interval 影响
translog每次写入先追加的日志,保证未 commit 数据可恢复flush 前不断增长,占用磁盘
写入请求的 refresh 参数有三个常用值:false(默认,不等待)、true(立刻刷新,开销最大)、wait_for(等下一次自动 refresh 完成,批量导入友好)。wait_for 在 refresh_interval 为 -1 时会一直等下去,此时需要显式 _refresh 或其他机制收尾。
数据安全并不依赖 flush:写入先落 translog,节点异常重启后会重放未 commit 的操作。flush 的价值在于把重放量降下来,缩短恢复窗口,所以长跑任务结束后做一次是划算的。
refresh_interval 的大小就是「近实时」延迟的量级:默认 1s 意味着刚写入的文档最多 1 秒后才可能被查出来,这行配置也常在压测时被误判成丢数据。

易错点

  • 把 refresh_interval 长期设为 -1 却没在导入结束后恢复,新数据一直搜不到 → 导入脚本里成对设置并补一次 _refresh
  • 频繁手动 _refresh 制造大量小段,加重后台合并与磁盘 I/O → 用 refresh=wait_for,或批量结束后统一刷一次
  • 把 flush 当成「让数据可搜索」的手段,实际上可见性只由 refresh 决定,flush 管的是落盘与恢复
  • 写后立刻读却用默认 refresh=false,偶发查不到就误判为丢数据 → 明确用 wait_for 或手动 _refresh
  • 在写入高峰做 flush 或调副本数,I/O 与分片复制压力叠加,查询延迟明显上升

数据来源与参考

  • Elasticsearch Guide: Refresh API
  • Elasticsearch Guide: Flush API
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌