分享好友 最新动态首页 最新动态分类 切换频道
es 10000深分页
2024-12-26 14:24


说明:
ElasticSearch 深度分页 是面试的高频题目,社群小伙伴要求,尼恩写个博客来介绍一下,于是,此文就出来了

  • 传统方式(from&size)
    顶部查询,查询10000以内的文档
    场景:需要实时获取顶部的部分文档。
    eg: 例如查询最新的订单。
  • Scroll 滚动游标 方式
    深度分页,用于非实时查询场景
    eg:需要全部文档,例如导出全部数据
  • Search After
    深度分页,用于实时查询场景

注意es版本,低版本不能使用,具体见后文

这是ElasticSearch最简单的分页查询 , from + size10000 +10需要查询的文档从10000 到 10010

以上命令是会报错的。

报错信息,指window默认是10000。

from&size为何不能获取10000个以上的文档

性能

为了性能,es限制了我们分页的深度,

es目前支持的最大的 max_result_window = 10000;

也就是说我们不能获取10000个以上的文档 , 当ES 分页查询超过一定的值(10000)后,会报错

怎么解决这个问题,首先能想到的就是调大这个window。

但这种方法只是暂时解决问题,当数据量越来越大,分页也越来越深,而且越会出OOM问题的。

from&size分页为何会OOM

协调节点或者客户端节点,需要讲请求发送到所有的分片

每个分片把from + size个结果,返回给协调节点或者客户端节点‘

协调节点或者客户端节点进行结果合并,如果有n个分片,则查询数据是 n * (from+size) , 如果from很大的话,会造成oom或者网络资源的浪费。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KimXpike-1647609673794)()]

例子

如请求第20页,Elasticsearch不得不取出所有分片上的第1页到第20页的所有文档,并做排序,最终再取出from后的size条结果作最终的返回

假设你有16个分片,则需要在coordinate node彙总到 shards* (from+size)条记录,即需要16*(20+10)记录后做一次全局排序

所以,当索引非常非常大(千万或亿),是无法使用from + size 做深分页的,分页越深则越容易OOM,

即便不OOM,也很消耗CPU和内存资源

结论是:

max_result_window 越大,副本越多,越容易OOM

所以不建议去 修改 max_result_window

可以看到,在分布式系统中,对结果排序的成本随分页的深度成指数上升。这就是 web 搜索引擎对任何查询都不要返回超过 10000 个结果的原因。

ES为了避免深分页,不允许使用分页(from&size)查询10000条以后的数据,

因此如果要查询第10000条以后的数据,要使用ES提供的 scroll(游标) 来查询

Scroll 滚动游标原理:

对一次查询生成一个游标 scroll_id , 后续的查询只需要根据这个游标scroll_id 去取数据,直到结果集中返回的 hits 字段为空,就表示遍历结束。

scroll_id 的生成可以理解为建立了一个临时的历史快照,或者可以理解为一个保存doc快照的临时的结果文件,快照文件形成之后,原doc的增删改查等操作不会影响到这个快照的结果。

Scroll 滚动游标可以简单理解为:

使用scroll就是一次把要用的数据都排完了,缓存起来

在遍历时,从这个快照里取数据,分批取出,

因此,游标可以增加性能的原因,Scroll 使用from+size还好

是因为如果做深分页,from+size 每次搜索都必须重新排序,非常浪费资源,而且容易OOM

Scroll 滚动游标使用过程:

使用 Scroll 进行分页读取过程如下:

先获取第一个 scroll_id,url 参数包括 /index/_type/ 和 scroll,

scroll 字段指定了scroll_id 的有效生存期,以分钟为单位,过期之后es 自动清理 快照数据(临时文件)。

如果文档不需要特定排序,可以指定按照文档创建的时间返回会使迭代更高效。

参数scroll=2m:

表示 srcoll_id 的生存期为2分钟。scroll就是把一次的查询结果缓存一定的时间,如scroll=2m则把查询结果在下一次请求上来时暂存2分钟,response比传统的返回多了一个scroll_id,下次带上这个scroll_id即可找回这个缓存的结果。

后续翻页, 通过上一次查询返回的scroll_id 来不断的取下一页,请求指定的 scroll_id 时就不需要 /index/_type 等信息了。

如果srcoll_id 的生存期很长,那么每次返回的 scroll_id 都是一样的,直到该 scroll_id 过期,才会返回一个新的 scroll_id。

每读取一页都会重新设置 scroll_id 的生存时间,所以这个时间只需要满足读取当前页就可以,不需要满足读取所有的数据的时间,1 分钟足以。

注意:

使用初始化返回的_scroll_id来进行请求,每一次请求都会继续返回初始化中未读完数据,并且会返回一个_scroll_id,这个_scroll_id可能会改变,因此每一次请求应该带上上一次请求返回的_scroll_id

每次发送scroll请求时,都要再重新刷新这个scroll的开启时间,以防不小心超时导致数据取得不完整

如果没有数据了,就会回传空的hits,可以用这个判断是否遍历完成了数据

scroll_id 的清理

srcoll_id 的存在会耗费大量的资源来保存一份当前查询结果集映像,并且会占用文件描述符。

为了防止因打开太多scroll而导致的问题,不允许用户打开滚动超过某个限制。

默认情况下,打开的滚动的最大数量为500.可以使用search.max_open_scroll_context群集设置更新此限制。

获取有多少个scroll滚动游标

虽然es 会有自动清理机制,但是,尽量保障所有文档获取完毕之后,手动清理掉 scroll_id 。

使用 es 提供的 CLEAR_API 来删除指定的 scroll_id

上述的 scroll search 的方式,官方的建议不用于实时文档的查询:

  • 因为每一个 scroll_id 生成的历史快照,对于数据的变更不会反映到快照上。

scroll 方式往往用于非实时处理大量数据的情况,比如要进行数据迁移或者索引变更之类的。

那么在实时情况下如果处理深度分页的问题呢?

es 给出了 search_after 的方式,这是在 >= 5.0 版本才提供的功能。

search_after 分页

search_after 分页的方式和 scroll 有一些显著的区别,

首先它是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。

为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _id 作为全局唯一值,其实使用业务层的 id 也可以。

search_after 使用

第一页的请求和正常的请求一样,

第二页的请求,使用第一页返回结果的最后一个数据的值,加上 search_after 字段来取下一页。

注意,使用 search_after 的时候要将 from 置为 0 或 -1

总结:search_after 适用于深度分页+ 排序,因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。

且返回的始终是最新的数据,在分页过程中数据的位置可能会有变更。

Search After深度翻页要点

每个文档具有一个唯一值的字段应该用作排序规范的仲裁器。否则,具有相同排序值的文档的排序顺序将是未定义的。

建议的方法是使用字段_id,它肯定包含每个文档的一个唯一值。

返回的结果

上面的请求会为每一个文档返回一个包含sort排序值的数组。

这些sort排序值可以被用于 search_after 参数里以便抓取下一页的数据。

比如,我们可以使用最后的一个文档的sort排序值,将它传递给 search_after 参数:

Search After

Search After的要点:

  • 它必须先要指定排序(因为一定要按排序记住坐标)
  • 必须从第一页开始搜起
  • 从第一页开始以后每次都带上 从而为无状态实现一个状态,

说白了就是把每次固定的from size偏移变成一个确定值,而查询则从这个偏移量开始获取size个doc(每个shard 获取size个,coordinate node最后汇总 shards*size 个。

Search After与sroll的原理基本相同:

Search After是Elasticsearch 5 新引入的一种分页查询机制,其实原理和scroll基本一样,但是不缓存结果,而是重新进行分片的排序计算

  • 传统方式(from&size)
    需要实时获取顶部的部分文档。例如查询最新的订单。
  • Scroll
    用于非实时查询
    需要全部文档,例如导出全部数据
  • Search After
    用于实时查询
    需要做到深度分页

最新文章
该股的最大炒作亮点是什么?潜在题材又是什么?验证成为手机用户,查看该股万隆原创动态分析报告
老铁们,今天行情,如果没有昨天那个会议利好和高开的走势,老白会觉得微涨还不错,加上美股那边已经跌了两天,而A股则是连涨两天,但是现在的情况好像是昨天那波高开低走是消失了一样,一点都没影响到A股,今天来到了3432点,成交量也有1.
国际站店铺装修指南:打造高转化率的视觉营销空间
尊敬的店主,您是否曾遇到这样的情况:您精心挑选了商品,却发现销售效果并不理想,顾客在进入店铺后很快流失?不用担心,今天就为大家分享一份宝贵的指南,教您如何打造一个高转化率的视觉营销空间。第一步:合理规划空间布局第二步:选用
目前有那些信息流广告(5个搜索引擎信息流广告效果和投放体验)
我们致力于提供一个高质量内容的交流平台。为落实国家互联网信息办公室依法管网、依法办网、依法上网的要求,为完善跟帖评论自律管理,为了保护用户创造的内容、维护开放、真实、专业的平台氛围,我们团队将依据本公约中的条款对注册用户和
百度网站收录提交,百度网站收录提交器
快速提升网站可见度与搜索引擎排名的必备技巧一、理解网站收录的重要性百度作为中国最大的搜索引擎,拥有庞大的用户群体和高度的市场占有率。为了确保您的网站能够被更多潜在用户发现并访问,网站是至关重要的一步。正确的提交方式不仅能加
一步到位,利用AI生成超逼真美女写真,轻松上手!
在这个科技飞速发展的年代,AI的应用已经渗透到我们生活的方方面面。其中,AI绘画、AI写真制作更是得到了广泛的关注。不少小伙伴们都曾幻想过,拥有一张属于自己的专属美女写真,甚至可以用它来当做社交平台的头像,或者送给好友作为惊喜。
Python爬虫入门实战(详细步骤)
爬虫这个功能,我个人理解是什么语言都能写的,只要能正常发送 HTTP 请求,将响应回来的静态页面模版 HTML 上把我们所需要的数据提取出来就可以了,原理很简单,这个东西当然可以手动去统计收集,但是
阿里云助力易点天下实现程序化广告+AI多维度效率提升
  12月12日,在第十二届中国企业全球形象高峰论坛现场,联合阿里云正式发布了在程序化广告领域的多项重要突破,这些成果主要基于阿里云平台PAI、通义大模型以及阿里云+云原生技术生成。  市场研究机构MAGNA最新发布的《全球广告预测》
观山湖区第一高级中学环境好不好
摘要:观山湖区第一高级中学的环境综合评价涵盖了校园设施、教学资源、师资力量等多个方面。小编从升学规划师的角度出发,深入分析学校环境对学长和教育质量的重要性,探讨该校在各方面的表现及其对学生未来发展的潜在影响。观山湖区第一高
遇到纠纷不用慌,“人民调解”帮你忙!“解纷芜优”指引来了
生活中可能遇到矛盾纠纷,如果闹上法庭,不仅要花时间和金钱,还会伤害人与人之间的和气……那么,如何更加妥善高效处理矛盾纠纷呢?快随小编来看看“人民调解”如何省时省心帮助纠纷双方解决问题吧现在可以通过“解纷芜优”在线申请调解啦
甲骨文谈存储:其实一开始我们就是认真的
当人们谈到iPhone的成功最大的因素之一就是软件与硬件最强大的结合。雷军也表示软硬件结合互联网是小米成功的核心。今天甲骨文高调宣布其存储设备并向业 内发出最强音---甲骨文的软件加上甲骨文的存储设备,就是要为企业级数据市场提供最好
相关文章
推荐文章
发表评论
0评