假设取的页数较大时(深分页),如请求第20页,Elasticsearch不得不取出所有分片上的第1页到第20页的所有文档,并做排序,最终再取出from后的size条结果作爲最终的返回值
假设你有16个分片,则需要在coordinate node彙总到 shards* (from+size)条记录,即需要16*(20+10)记录后做一次全局排序
所以,当索引非常非常大(千万或亿),是无法使用from + size 做深分页的,分页越深则越容易OOM,即便不OOM,也很消耗CPU和内存资源
因此ES使用
index.max_result_window:10000
作爲保护措施 ,即默认 from + size 不能超过10000,虽然这个参数可以动态修改,也可以在配置文件配置,但是最好不要这麽做,应该改用ES游标来取得数据
scroll游标原理
可以把 scroll 理解爲关系型数据库里的 cursor,因此,scroll 并不适合用来做实时搜索,而更适用于后台批处理任务,比如群发
scroll 具体分爲初始化和遍历两步
初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照
在遍历时,从这个快照里取数据
也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果
游标可以增加性能的原因,是因为如果做深分页,每次搜索都必须重新排序,非常浪费,使用scroll就是一次把要用的数据都排完了,分批取出,因此比使用from+size还好
具体实例
初始化
请求
注意要在URL中的search后加上
scroll=1m
,不能写在request body中,其中1m
表示这个游标要保持开启1分钟可以指定size大小,就是每次回传几笔数据,当回传到没有数据时,仍会返回200成功,只是hits裡的hits会是空list
在
ElasticSearch - 解决ES的深分页问题 (游标 scroll)
最新推荐文章于 2024-12-17 12:22:13 发布