ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何解决ES深度分页

如何解决ES深度分页 在Elasticsearch中深度分页指的是请求靠后的页码如第1000页每页20条时性能急剧下降甚至内存溢出的问题。面试官期望你理解ES分页原理并给出合理的解决方案。一、为什么深度分页慢ES默认的分页通过from size实现例如请求第1000页每页20条from 19980, size 20。协调节点会向所有分片发送查询每个分片必须返回from size条文档即19980条给协调节点。协调节点对收到的分片数 × (fromsize)条文档进行全局排序截取from到fromsize的文档返回。代价随着from增大每个分片需要返回的数据量线性增长网络IO、内存、CPU开销剧增。二、解决方案1. 避免深度分页业务折衷限制用户只能查看前100页或前500页。很多搜索引擎也这样设计改用“滚动加载”或“加载更多”的方式而不是页码跳转。2.search_after——推荐用于实时深度分页原理使用上一页最后一条文档的排序值如_id或时间戳作为下一次查询的起点。步骤第一次查询正常sort和size并获取最后一条文档的排序值。下一页在请求中加上search_after: [last_sort_value]。优点无深度分页性能问题每次查询只取size条。支持实时数据可以看到新插入的文档。缺点必须指定排序字段且最好是唯一值如_id。不能随机跳页只能顺序翻页。3.scroll—— 用于批量导出或非实时遍历原理执行scroll查询时ES会生成当前时间点的快照并返回一个scroll_id后续通过该ID批量拉取数据。用法GET /order/_search?scroll1m { size: 1000 }然后用scroll_id持续拉取。优点适合处理大量数据如全量导出。每次请求开销较小。缺点占用内存资源保留搜索上下文。不适用于实时分页数据是快照不能反映后续变更。scroll结果顺序可能不一致依赖排序。4. 使用point in time(PIT) search_after(ES 7.10)这是目前官方推荐的深分页实时方案先创建一个 PIT代替索引名固定查询时间点。使用search_after基于该 PIT 进行分页既能避免深度分页问题又能保证数据一致性。三、各方案对比方案实时性随机跳页性能深度适用场景from/size实时✅极差深度大时不可用前几百页数据量小search_after实时❌ 只能下一页好Web UI 滚动加载scroll快照❌好但占用资源全量导出、批处理PIT search_after快照或实时❌好兼顾一致性与深度四、实际项目中的设计原则默认查询使用from/size限制最大from值如 10000超过则返回错误或拒绝。用户滚动加载改用search_after前端记录最后一条文档的排序值。导出全量数据使用scroll并设置合理的scroll超时时间如 10 分钟用完及时清除scroll_id。业务监控检测到深分页请求from过大时打印警告或限流。
返回列表