基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Elasticsearch 中Refresh 和 Flush的区别?

知识点图片

在 Elasticsearch 中,RefreshFlush 是两个非常关键但容易混淆的概念。简单来说,它们的区别在于:

  • Refresh(刷新): 解决的是数据 “可见性” 问题(让数据可以被搜索到)。
  • Flush(冲刷): 解决的是数据 “持久化” 问题(将数据真正写入磁盘,防止丢失)。

为了深入理解,我们需要了解 Elasticsearch(基于 Lucene)写入数据的流程。


1. 核心流程图解

当一个文档被写入 ES 时,流程如下:

  1. 写入 Buffer & Translog: 数据首先被写入内存缓冲区(Memory Buffer),同时追加到事务日志(Translog)中(为了防止断电数据丢失)。
  2. Refresh(变为可搜索): 默认每 1 秒,ES 会将 Memory Buffer 中的数据生成一个新的 Lucene Segment,并放入 文件系统缓存(Filesystem Cache) 中。
    • 此时:数据可以被搜索到了,但还在内存中,没有真正落盘。
  3. Flush(变为持久化): 当 Translog 达到一定大小或时间(默认 30 分钟),会触发 Flush。ES 会执行 fsync 将文件系统缓存中的 Segment 写入物理磁盘,并清空 Translog。
    • 此时:数据安全地存储在磁盘上了。

2. 深度解析:Refresh

定义:
Refresh 操作是将内存缓冲区(Memory Buffer)中的文档生成一个新的 Lucene Segment,并将其打开以供搜索的过程。

  • 目的: 实现 近实时搜索(Near Real-Time, NRT)
  • 发生了什么:
    1. Memory Buffer 被清空。
    2. 一个新的 Segment 被创建在操作系统的 Filesystem Cache 中(注意:此时还没有 fsync 到物理磁盘)。
    3. 该 Segment 被打开,使得里面的文档可以被搜索查询。
  • 触发时机:
    • 默认每 1 秒自动触发一次(由 index.refresh_interval 控制)。
    • 当 Memory Buffer 满了时。
    • 手动调用 _refresh API。
  • 性能影响:
    • Refresh 是有成本的(创建 Segment、打开文件句柄)。
    • 优化建议: 在批量导入大量数据时,建议将 refresh_interval 设置为 -1(关闭自动刷新)或调大时间,导入完成后再改回来,能显著提高写入速度。

3. 深度解析:Flush

定义:
Flush 操作是将文件系统缓存中的数据强制写入物理磁盘(fsync),并执行 Lucene Commit,最后清空 Translog 的过程。

  • 目的: 确保数据 持久化,释放 Translog 空间。
  • 发生了什么:
    1. 内存中所有未落盘的 Segment 被强制 fsync 到物理磁盘。
    2. 写入一个 Commit Point 文件,标记这次提交。
    3. Translog 被清空/截断(因为数据已经安全落盘,不再需要日志来恢复了)。
  • 触发时机:
    • Translog 大小达到阈值(默认 512MB,index.translog.flush_threshold_size)。
    • 距离上次 Flush 的时间达到阈值(默认 30 分钟)。
    • 手动调用 _flush API。
  • 性能影响:
    • Flush 是非常昂贵的操作(涉及物理磁盘 IO)。
    • 通常不需要手动干预,ES 会自动管理。

4. Translog 的作用(连接 Refresh 和 Flush 的桥梁)

你可能会问:既然 Refresh 只是把数据放到内存缓存里,那如果服务器断电了,数据岂不是丢了?

这就是 Translog 存在的意义:

  • 数据写入时是 同步 写入 Translog 的(默认配置)。
  • 即使 Refresh 后的数据还在内存(Filesystem Cache)中,如果此时断电,ES 重启后会重放 Translog 中的操作,将数据恢复回来。
  • Flush 的作用就是“截断”Translog。一旦数据真正落盘(Flush),Translog 里的旧记录就可以删除了。

5. 总结对比表

特性 Refresh (刷新) Flush (冲刷)
核心目标 可见性 (Visibility) 持久性 (Durability)
操作对象 Memory Buffer -> Filesystem Cache Filesystem Cache -> Physical Disk
Lucene 动作 Reopen (打开新段) Commit (提交并 fsync)
Translog 不影响 Translog 清空/截断 Translog
搜索实时性 决定了数据多久能被搜到 (默认 1s) 不直接影响搜索可见性
物理落盘 (数据仍在 OS Cache) (执行 fsync)
性能开销 中等 (频繁发生) 高 (低频发生)
常见调优 批量写入时调大或关闭 一般保持默认,极少手动触发

一句话总结:
Refresh 让你能搜到刚写进去的数据(近实时),而 Flush 确保数据真正写到硬盘上(不丢失)。

00:00
00:00