Elasticsearch全量分页可行性

前言

在分布式系统中深度分页

理解为什么深度分页是有问题的,我们可以假设在一个有 5 个主分片的索引中搜索。 当我们请求结果的第一页(结果从 1 到 10 ),每一个分片产生前 10 的结果,并且返回给协调节点,协调节点对 50 个结果排序得到全部结果的前 10 个。

现在假设我们请求第 1000 页--结果从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果以外。 然后协调节点对全部 50050 个结果排序最后丢弃掉这些结果中的 50040 个结果。

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

分页方式

  • from+size
    常见深度分页方式。from表示从第几行开始,size表示查询多少条文档。from默认为0,size默认为10, size的大小不能超过index.max_result_window这个参数的设置,默认为10,000。
  • scroll
    对某次查询生成一个游标 scroll_id , 后续的查询只需要根据这个游标去取数据,直到结果集中返回的 hits 字段为空,就表示遍历结束。scroll_id 的生成可以理解为建立了一个临时的历史快照,在此之后的增删改查等操作不会影响到这个快照的结果。
  • search_after
    提供一个live cursor来规避消耗存储和时间的性能问题,将上一页查询的最后一条数据作为下一条数据的搜索条件,必须有全局唯一字段来排序,如业务唯一标识字段或elasticsearch自带的_id字段。
    适用于深度分页+ 排序,因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。且返回的始终是最新的数据,在分页过程中数据的位置可能会有变更。

优劣分析

分页方式 是否有页数限制 是否可以跳页 性能 耗费资源 实时性 常用场景
from+size 有,受参数限制,可调整 分页越深,性能指数倍下降 分页越深,耗费资源指数倍增长 实时 常见的搜索场景都可以满足,需限制页数
scroll 第一次查询时缓存查询结果耗费资源较多,后续基本无耗费 非实时 后台批量导出任务、数据迁移任务
search_after 第一次查询时缓存查询结果耗费资源较多,后续按上次查询结果取数据 实时 有实时性要求的批量任务

最终方案

思考:业务方哪种需求需要用elasticsearch搜索查看超过10000条的数据?考虑尽可能多的条件过滤出真实需要的数据

  • 业务自主查询限制页数。采用尽可能多的查询条件,限制查询结果在10000条以内,使用from+size灵活查询
  • 性能与业务择中,业务侧限制分页方式。只能查询下一页,无法跳页,此方式可使用search_after查询

猜你喜欢

转载自blog.csdn.net/yml_try/article/details/108648211