scroll 做什么
scroll 在发起查询时创建一份快照上下文,之后用 scroll_id 一批批取回全部结果,适合全量导出与离线处理。代价是上下文存活期间相关段文件不会被合并,还会在堆内存里维持状态,因此遍历结束必须显式清理。
基本信息
| 创建上下文 | POST /<index>/_search?scroll=1m 并携带 size |
|---|---|
| 翻页 | POST /_search/scroll 传 scroll_id 与新的保持时间 |
| 收尾 | DELETE /_search/scroll 显式释放,不要只依赖超时 |
| 结果视图 | 返回发起时刻的快照,期间的变更不影响本次遍历 |
| 适用规模 | 全量导出与离线计算;深分页场景更适合 PIT 加 search_after |
典型使用场景
- 全量导出索引数据到文件或另一个存储
- 离线统计:需要遍历全部文档做批处理
- 数据迁移前的核对:按批次拉取并比对条数
- 重建派生数据:把老数据逐批读出后重新加工写入
- 对超大结果集做分批处理,避免单次请求返回过多内容
遍历流程
遍历流程
# 创建 scroll 上下文,第一批结果随响应返回
POST /my-index/_search?scroll=1m
{ "size": 1000, "query": { "match_all": {} } }
# 用 scroll_id 继续取下一批,并刷新保持时间
POST /_search/scroll
{ "scroll": "1m", "scroll_id": "<上一步返回的 scroll_id>" }
# 遍历结束后显式释放上下文
DELETE /_search/scroll
{ "scroll_id": ["<scroll_id>"] }
# 查看存活的上下文数量,排查有没有泄漏
GET /_nodes/stats/indices/search?filter_path=**.open_contexts参数与取舍
| 参数 | 作用 | 注意 |
|---|---|---|
| scroll | 上下文保持时间,如 1m | 时间太短会让批次之间失效 |
| size | 每批返回的文档数 | 过大导致单批耗时长、上下文易超时 |
| scroll_id | 批次游标 | 每批可能返回新 id,要用最新值 |
| DELETE 释放 | 主动清理上下文 | 遍历结束必须调用 |
scroll 返回的是发起时刻的视图,期间被删除或更新的文档仍按旧版本返回;数据量大时优先考虑 PIT 加 search_after,官方已不再推荐用 scroll 做深分页。
批量导出时 size 控制在几百到几千之间比较稳;每批之间更新 scroll 的保持时间可以续命,避免长任务中途因上下文过期而中断。