Blog

Keep up to date with the latest news

第6篇:刷新Refresh机制:数据为什么需要Refresh?Refresh又是怎么做的?

一、引言:为什么需要 Refresh?

在 TongSearch中,写入成功 ≠ 立即可查询。

这背后最关键的一个机制就是:

Refresh(刷新)机制

它决定了写入的数据何时可被搜索到,而不是什么时候写入成功。

二、数据写入与可见性的区别

写入流程回顾:

Index 请求

写入内存 buffer(RAM) + Translog

Lucene 的 segment 并未立即更新

Lucene 查询无法看到这些内存数据

直到 Refresh 发生

简而言之:

写入内存 ≠ Lucene 可搜索

刷新(refresh) ≈ 把内存数据提交为 segment,让 Lucene 知道它存在

三、什么是 Refresh?

Refresh 是 TongSearch/Lucene 中的一个机制,用于:

将内存中的文档 buffer(SegmentWriter buffer)刷新为一个新的 segment,使其变得可搜索(searchable)。

其本质是调用:

IndexWriter.getReader(); // 开启一个新的 IndexReader

而生成一个新的 Searcher,以支持后续查询请求。

四、Refresh 的触发机制

TongSearch中 Refresh 有三种触发方式:

触发方式

描述

自动刷新

默认每隔 1 秒执行一次,由 IndexSettings.INDEX_REFRESH_INTERVAL_SETTING 控制

手动刷新

用户显式调用 _refresh API

实时刷新(Near Real-Time)

特定操作(如 GET)需要时,可能强制打开 reader 实现“伪实时”读取

示例:修改 refresh interval

PUT my-index/_settings

{

"index": {

"refresh_interval": "30s"

}

}

五、刷新流程详解

1)文档写入后进入内存 buffer

所有写入数据暂存于 Lucene 的 RAM buffer 中

写入也同步记录到 Translog,以确保崩溃后能恢复

2)调用 refresh() 方法

刷新流程本质:

IndexWriter.getReader() // 开启新的 reader

Lucene 将会:

创建一个新的 segment(内存 segment)

将这些 segment 暴露为一个新的 IndexReader

将新的 reader 更新到 IndexShard.searcher 中,供搜索使用

这一步是轻量级的,不涉及磁盘写入。

3)旧 Searcher 被关闭(延迟释放)

TongSearch使用 SearcherManager 管理 reader

老的 reader 不会立刻释放(Zero Downtime Search)

支持多个并发查询仍能读取老版本数据(直到 GC)

六、Refresh 与 Flush 的区别

操作

是否写磁盘

是否可查询

是否清理 translog

Refresh

❌ 否

✅ 是

❌ 否

Flush

✅ 是

✅ 是

✅ 是(创建 commit point)

Refresh ≠ 持久化,只是数据“可搜索”而非“可恢复”!

要确保写入能 survive 重启,还需等 translog 落盘(或 flush)。

七、Refresh 与性能的关系

频繁刷新 = 更多 segment = 查询性能下降

所以在一些场景下,应该:

增大 refresh interval,降低写入系统压力

批量导入时设置为 -1(禁止自动刷新),导入完成后手动 _refresh

PUT /my-index/_settings

{

"index": {

"refresh_interval": "-1"

}

}

八、Refresh 与实时搜索

TongSearch是 Near Real-Time 搜索系统,默认 1 秒可见。

你可以控制“是否等待 refresh 后可见”:

示例:立即可见写入

POST /my-index/_doc/1?refresh=wait_for

{

"title": "立即可见"

}

九、总结

Refresh 本质

将内存 buffer 刷新为 Lucene 可查询的 segment

默认触发

每隔 1 秒一次,可配置或关闭

是否写磁盘

否,仅在内存中创建 reader

是否可搜索

是,刷新后 Searcher 才能看到数据

适用场景

提高查询可见性,但频繁刷新会增加 segment 数量