当前位置: 首页 > 未分类>阅读正文

elasticSearch使用from+size大于1w报错

2022.7.14 朱丰华 160 次 留下评论 1127字

默认不允许使用 from 的大小超过1w。

如果需要修改该设定值,可以设置:

PUT _settings
{
    "index_name": {
        "max_result_window": "10000000"
    }
}

Search接口进行翻页的方式主要有两种,一是size+from的翻页方式,这种翻页方式存在很大的性能瓶颈,时间复杂度O(n),空间复杂度O(n)。其每次查询都需要从第1页翻到第n页,但是只有第n页的数据需要返回给用户。那么之前n-1页都是做的无用功。如果翻的更深,那么消耗的系统资源更是翻倍增长,很容易出现OOM,系统各项指标出现异常。举个例子,假设每个文档在协调节点进行merge的ScoreDoc需要16字节,那么翻到一亿条时候,需要1.6G的内存,如果多来几个并发,普通用户的计算机根本扛不住这么大的内存开销,前几页就几十毫秒,翻到 10 页或者几十页的时候,基本上就要 5~10 秒才能查出来一页数据了。因此,很多产品在功能上直接禁止用户深度翻页来避免这种技术难题。

searchAfter:

Search接口另一种翻页方式是SearchAfter,时间复杂度O(n),空间复杂度O(1)。SearchAfter是一种动态指针的技术,每次查询都会携带上一次的排序值,这样下次取结果只需要从上次的位点继续扫数据,前提条件也是该字段是数值类型且设置了docValue。举个例子,假设”val_1″是数值类型的字段,然后使用Search接口查询时候添加Sort(“val_1”),那么response中可以拿到最后一条数据的”val_1″的值,,也就是response中sort字段的值,然后下次查询将该值放在query中的searchAfter参数中,下次查询就可以在上一次结果之后继续查询,如此反复,最后可以翻页很深,内存消耗相比size+from的方式降低了数倍。该方式效果类似于我们直接在bool查询中主动加一个rangeFilter,可以达到类似的效果。表面看这种方案能将查询速度降到O(1)的复杂度,实际上其内部还是会扫sort字段的docValue,翻页越深,则扫docValve越多,因此复杂度和翻页深度成正比,越往后查询越慢,但是相比size+from的方式,至少可以完成深度翻页的任务,不至于OOM,速度勉强可以接受。SearchAfter的翻页方式在性能上有了质的提升,但是其限制了用户只能一页一页往后翻,无法跳页,因此很多产品在功能设计时候是不允许跳页的,只能一页一页往后翻,也是有一定的技术原因的。

这里的 searchAfter,类似 search scroll api,游标查询。手机app一般都用这种方式,向下滚动时自动加载新一页内容,不允许随便翻页。

本篇完,还有疑问?留下评论吧

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注