首页/数据/NoSQL 速查/scroll 遍历大批量结果
Elasticsearch89 条

scroll 遍历大批量结果

scroll 在查询时创建快照上下文,用 scroll_id 分批取回全部结果,适合全量导出与离线处理;代价是期间段文件不能合并、占用资源。

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

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 的保持时间可以续命,避免长任务中途因上下文过期而中断。

易错点

  • 忘记 DELETE 清理 scroll,上下文会持续占用段引用与堆内存,累积后可能拖慢甚至拖垮节点
  • 每批耗时超过 scroll 保持时间会让上下文超时失效,size 设得过大会把任务直接打断在中间
  • 把 scroll 当普通分页使用:它不支持跳页,也不反映最新数据,实时检索场景应改用 search_after
  • 多批次遍历时沿用旧的 scroll_id 而不使用每批返回的最新值,后续请求会报上下文不存在

数据来源与参考

  • Elasticsearch Guide: Scroll API
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌