如何在Elasticsearch中进行深分页

如何在Elasticsearch中进行深分页

业务背景

在传统业务系统中,一个常见的信息展现方式就是“分页列表”,随着数据量的增大,就会遇到“深分页”问题。比如用户一页一页的翻,一直翻到第5万页。比如导出全部列表数据到excel,实现时一页一页的把数据追加到excel,直到导出全部数据。“深分页”通常的一个问题就是:随着页数越来越大,ES或者关系数据库响应越来越慢,甚至内存溢出OOM!其中的原理是什么呢?如何在ES中进行深分页呢?

技术原理

  • 分页的本质
    分页的本质是从“大的数据集”中取出一部分。比如10000条记录,每页10条数据。取第二页即第11条到20条数据。ES或者数据库怎么知道哪些数据是第二部分(第2页),哪些是第三部分(第3页)呢?答案是ES或者数据库不知道,所以正确的分页必须要指定分页的顺序,即要有order by或者sort语句

  • 单机数据库系统分页
    单机数据库系统有一种分页实现叫做“先正序排后倒排序排”。即先对"offset+limit"的数据集根据order字段正序排列,然后再倒序找到limit条数据。

在这里插入图片描述

  • 分布式数据库系统分页

分布式数据库系统相对于单机数据库系统,在各个节点取出limit条数据后,还要将各个节点的"limit"条数据汇总到master节点。由master节点对limit*N(节点数)再排序,找到最终的limit条数据返回给应用程序。所以在深分页时,offset+limit过大,要排序的数据过多,对于内存分页数据库很容易超过进程的内存限制,产生OOM!

分页方式

在ES中有三种方式可以实现分页:from+size、scroll、search_after

  • from+size
    ES的标准分页方法是from+size。from相当于postgresql的offset,size相当于limit的作用。每页10条数据,获取第11页的数据,其语法如下:
POST rzfx-sqlinfo/sqlinfo/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "architect.keyword": {
              "value": "郭锋"
            }
          }
        },
        {
          "range": {
            "NRunTime": {
              "lte": 100
            }
          }
        }
      ]
    }
  },
  "size": 10,
  "from": 100
}

ES为了保证分页不占用大量的堆内存,避免OOM,参数 index.max_result_window 设置了 from+size的最大值为10000。即每页10条的话,最多可以翻到1000页。index的全部参数可以通过以下语句查看:

GET /rzfx-sqlinfo/_settings?flat_settings=true&include_defaults=true

对于结构比较简单、size比较小的文档,可以适当的扩大index.max_result_window参数,部分实现深分页。

  • scroll

  • search_after

最佳实践

转载于:https://www.cnblogs.com/wangzhen3798/p/10070977.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值