ElasticSearch - 解决ES的深分页问题 (游标 scroll)
https://www.jianshu.com/p/f4d322415d29
1.简介
ES为了避免深分页,不允许使用分页(from&size)查询10000条以后的数据,因此如果要查询第10000条以后的数据,要使用ES提供的 scroll(游标) 来查询
假设取的页数较大时(深分页),如请求第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游标来取得数据
2.scroll游标原理
可以把 scroll 理解爲关系型数据库里的 cursor,因此,scroll 并不适合用来做实时搜索,而更适用于后台批处理任务,比如群发
scroll 具体分爲初始化和遍历两步
初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照
在遍历时,从这个快照里取数据
也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果
游标可以增加性能的原因,是因为如果做深分页,每次搜索都必须重新排序,非常浪费,使用scroll就是一次把要用的数据都排完了,分批取出,因此比使用from+size还好
3.具体实例
初始化
请求
注意要在URL中的search后加上scroll=1m,不能写在request body中,其中1m表示这个游标要保持开启1分钟
可以指定size大小,就是每次回传几笔数据,当回传到没有数据时,仍会返回200成功,只是hits裡的hits会是空list
在初始化时除了回传_scroll_id,也会回传前100笔(假设size=100)的数据
request body和一般搜索一样,因此可以说在初始化的过程中,除了加上scroll设置游标开启时间之外,其他的都跟一般的搜寻没有两样 (要设置查询条件,也会回传前size笔的数据)
POST 127.0.0.1:9200/my_index/_search?scroll=1m `注意这里的地址`
{
"query":{
"range":{
"createTime": {
"gte": 1522229999999
}
}
},
"size": 1000
}
返回结果
{
"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAfv5-FjNOamF0Mk1aUUhpUnU5ZWNMaHJocWcAAAAAAH7-gBYzTmphdDJNWlFIaVJ1OWVjTGhyaHFnAAAAAAB-_n8WM05qYXQyTVpRSGlSdTllY0xocmhxZwAAAAAAdsJxFmVkZTBJalJWUmp5UmI3V0FYc2lQbVEAAAAAAHbCcBZlZGUwSWpSVlJqeVJiN1dBWHNpUG1R",
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 84,
"max_score": 1,
"hits": [
{
"_index": "video1522821719",
"_type": "doc",
"_id": "84056",
"_score": 1,
"_source": {
"title": "三个院子",
"createTime": 1522239744000
}
}
....99 data
]
}
}
遍历数据
请求
使用初始化返回的_scroll_id来进行请求,每一次请求都会继续返回初始化中未读完数据,并且会返回一个_scroll_id,这个_scroll_id可能会改变,因此每一次请求应该带上上一次请求返回的_scroll_id
要注意返回的是_scroll_id,但是放在请求裡的是scroll_id,两者拼写上有不同
且每次发送scroll请求时,都要再重新刷新这个scroll的开启时间,以防不小心超时导致数据取得不完整
POST 127.0.0.1:9200/_search/scroll?scroll=1m `注意地址`
{
"scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAdsMqFmVkZTBJalJWUmp5UmI3V0FYc2lQbVEAAAAAAHbDKRZlZGUwSWpSVlJqeVJiN1dBWHNpUG1RAAAAAABpX2sWclBEekhiRVpSRktHWXFudnVaQ3dIQQAAAAAAaV9qFnJQRHpIYkVaUkZLR1lxbnZ1WkN3SEEAAAAAAGlfaRZyUER6SGJFWlJGS0dZcW52dVpDd0hB"
}
返回结果
如果没有数据了,就会回传空的hits,可以用这个判断是否遍历完成了数据
{
"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAdsMqFmVkZTBJalJWUmp5UmI3V0FYc2lQbVEAAAAAAHbDKRZlZGUwSWpSVlJqeVJiN1dBWHNpUG1RAAAAAABpX2sWclBEekhiRVpSRktHWXFudnVaQ3dIQQAAAAAAaV9qFnJQRHpIYkVaUkZLR1lxbnZ1WkN3SEEAAAAAAGlfaRZyUER6SGJFWlJGS0dZcW52dVpDd0hB",
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 84,
"max_score": null,
"hits": []
}
}
优化scroll查询
在一般场景下,scroll通常用来取得需要排序过后的大笔数据,但是有时候数据之间的排序性对我们而言是没有关系的,只要所有数据都能取出来就好,这时能够对scroll进行优化
初始化
使用_doc去sort得出来的结果,这个执行的效率最快,但是数据就不会有排序,适合用在只想取得所有数据的场景
POST 127.0.0.1:9200/my_index/_search?scroll=1m
{
"query": {
"match_all" : {}
},
"sort": [
"_doc"
]
}
}
清除scroll
虽然我们在设置开启scroll时,设置了一个scroll的存活时间,但是如果能够在使用完顺手关闭,可以提早释放资源,降低ES的负担
DELETE 127.0.0.1:9200/_search/scroll
{
"scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAdsMqFmVkZTBJalJWUmp5UmI3V0FYc2lQbVEAAAAAAHbDKRZlZGUwSWpSVlJqeVJiN1dBWHNpUG1RAAAAAABpX2sWclBEekhiRVpSRktHWXFudnVaQ3dIQQAAAAAAaV9qFnJQRHpIYkVaUkZLR1lxbnZ1WkN3SEEAAAAAAGlfaRZyUER6SGJFWlJGS0dZcW52dVpDd0hB"
}
4.转发连接
https://blog.csdn.net/weixin_40341116/article/details/80821655
ElasticSearch - 解决ES的深分页问题 (游标 scroll)的更多相关文章
- solr深分页,游标操作分页,解决性能问题
solr深分页,游标操作分页,解决性能问题 @Test public void pageByCursor() { try { solrServer.connect(); String query = ...
- ES scroll(ES游标) 解决深分页
ES scroll(ES游标) 解决深分页. Why 当Elasticsearch响应请求时,它必须确定docs的顺序,排列响应结果.如果请求的页数较少(假设每页20个docs), Elasticse ...
- 【分页问题】elasticsearch 深分页问题以及解决方法
本文主要参考: 1.https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html ...
- Elasticsearch from/size-浅分页查询-深分页 scroll-深分页search_after深度查询区别使用及应用场景
Elasticsearch调研深度查询 1.from/size 浅分页查询 一般的分页需求我们可以使用from和size的方式实现,但是这种的分页方式在深分页的场景下应该是避免使用的.深分页的页次增加 ...
- Elasticsearch由浅入深(七)搜索引擎:_search含义、_multi-index搜索模式、分页搜索以及深分页性能问题、query string search语法以及_all metadata原理
_search含义 _search查询返回结果数据含义分析 GET _search { , "timed_out": false, "_shards": { , ...
- ElasticSearch解决深度分页性能存在的问题使用scoll来解决
现在我们全局搜索全部的数据,每次返回3条, 从 scroll 请求返回的结果反映了 search 发生时刻的索引状态,就像一个快照.后续的对文档的改动(索引.更新或者删除)都只会影响后面的搜索请求. ...
- 查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题
开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降. 有没有什么办法,能解决深分页的问题呢? 本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 1. ...
- 【ELK】【docker】6.Elasticsearch 集群启动多节点 + 解决ES节点集群状态为yellow
本章其实是ELK第二章的插入章节. 本章ES集群的多节点是docker启动在同一个虚拟机上 ====================================================== ...
- MySQL 千万数据库深分页查询优化,拒绝线上故障!
文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 优化项目代码过程中发现一个千万级数据深分页问题,缘由是这样的 库里有一张耗材 MCS_PROD 表,通过同步 ...
随机推荐
- [CSP-S模拟测试]:Walker(数学)
题目传送门(内部题86) 输入格式 第一行$n$接下来$n$行,每行四个浮点数,分别表示变换前的坐标和变换后的坐标 输出格式 第一行浮点数$\theta$以弧度制表示第二行浮点数$scale$第三行两 ...
- REST framework 之 分页
DRF分页组件 为什么要使用分页 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输 ...
- 搜索引擎算法研究专题七:Hilltop算法
搜索引擎算法研究专题七:Hilltop算法 2017年12月19日 ⁄ 搜索技术 ⁄ 共 1256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 HillTop也是搜索引擎结果排序的专利,是Google工 ...
- leetcode-easy-array-122 best time to buy and sell stocks II
mycode 69.45% class Solution(object): def maxProfit(self, prices): """ :type prices: ...
- CentOS7 如何挂载网络设备
CentOS 自动挂载网络设备的方法 手动挂载: [root@mysql ~]# mount -o username=USER,password=PASSWORD //192.168.10.212/z ...
- 淘淘相关工具类【json,httpClient,id,FTP,exception,cookie(包括共享cookie的设置等)】
json package com.taotao.common.utils; import java.util.List; import com.fasterxml.jackson.core.JsonP ...
- 我们建了一个 Golang 硬核技术交流群(内含视频福利)
目录 目录 Golang 是什么? 我们为什么选择 Golang? Golang 是云时代的宠儿! 我们搞了一场 Golang 入门直播 Golang 是什么? Golang 是谷歌 2009 年发布 ...
- Linux_RHEV虚拟化_基础理论&KVM
目录 目录 RHEV KVM Full 完全虚拟化 PV半虚拟化 Full和PV最大的区别 HVMHardware Virtual Manager硬件辅助虚拟化 Setup KVM Use the v ...
- Delphi XE2 之 FireMonkey 入门(39) - 控件基础: TScrollBox、TVertScrollBox、TFramedScrollBox、TFramedVertScrollBox
Delphi XE2 之 FireMonkey 入门(39) - 控件基础: TScrollBox.TVertScrollBox.TFramedScrollBox.TFramedVertScrollB ...
- webpack中的 chunk,module,bundle的区别,以及hidden modules是什么
hidden modules是什么: chunk,module,bundle的区别 总结: module是指任意的文件模块,等价于commonjs中的模块 chunks是webpack处理过程中被分组 ...