ES理论:分页查询方案及优化策略

文章目录

  • 前言
  • [常见的 Elasticsearch 分页设计方案](#常见的 Elasticsearch 分页设计方案)
    • [1. `from + size` 分页 (浅分页)](#1. from + size 分页 (浅分页))
    • [2. `scroll` 分页 (游标分页/深分页)](#2. scroll 分页 (游标分页/深分页))
    • [3. `search_after` 分页 (搜索后分页)](#3. search_after 分页 (搜索后分页))
    • [4. 基于 `PIT` (Point In Time) 的 `search_after` 分页](#4. 基于 PIT (Point In Time) 的 search_after 分页)
  • 方案总结与对比
  • 核心建议
  • 资料获取

前言

博主介绍:✌目前全网粉丝4W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。

涵盖技术内容:Java后端、大数据、算法、分布式微服务、中间件、前端、运维等。

博主所有博客文件目录索引:博客目录索引(持续更新)

CSDN搜索:长路

视频平台:b站-Coder长路

常见的 Elasticsearch 分页设计方案

1. from + size 分页 (浅分页)

这是最直观、最常见的分页方式,类似于 MySQL 的 LIMIT offset, size

  • 工作原理from 指定了跳过的初始文档数量,size 指定了返回的最大文档数量。
  • 例子:查询第 6-10 条数据(即第 2 页,每页 5 条)。
json 复制代码
GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "from": 5,  // 跳过前5条
  "size": 5   // 返回5条
}

2. scroll 分页 (游标分页/深分页)

专为一次性处理大量数据(如数据导出、全量重建索引)而设计,不适合实时用户请求。

  • 工作原理 :首次查询创建一个快照和游标,后续请求使用这个游标来获取剩余结果。搜索上下文会在指定时间(如 1m)内保持活跃。
  • 例子:导出所有符合条件的数据。

a. 初始化 scroll 请求

json 复制代码
GET /my_index/_search?scroll=1m  // 保持搜索上下文1分钟
{
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  },
  "size": 100  // 每次滚动返回100条
}

响应中会包含一个 _scroll_id

b. 后续获取请求

json 复制代码
POST /_search/scroll
{
  "scroll": "1m",
  "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC...(很长的字符串)"
}

3. search_after 分页 (搜索后分页)

ES 5.0 引入,是进行深分页的最佳实践,适用于需要实时、有序地翻看大量数据的场景。

  • 工作原理 :使用上一页结果中的排序值作为"锚点",来获取下一页的结果。它避免了 from + size 深度分页的性能问题。
  • 要求 :必须指定一个或多个唯一的、不重复的排序字段(通常包括 _id)。
  • 例子:按时间戳和 ID 进行深度分页。

a. 获取第一页

json 复制代码
GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 10,
  "sort": [
    {"create_time": "desc"},  // 主排序字段
    {"_id": "asc"}            // 确保排序唯一性
  ]
}

b. 获取第二页及以后

使用第一页最后一条记录的排序值。

json 复制代码
GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 10,
  "sort": [
    {"create_time": "desc"},
    {"_id": "asc"}
  ],
  "search_after": [
    "2023-10-27T08:00:00.000Z",  // 上一页最后一条记录的 create_time
    "abc123"                     // 上一页最后一条记录的 _id
  ]
}

4. 基于 PIT (Point In Time) 的 search_after 分页

search_after 的增强版,解决了在分页过程中索引可能发生变化(如数据删除、更新)导致的结果不一致问题。

  • 工作原理 :先创建一个"时间点"(PIT),这个时间点会冻结索引的视图,保证在整个分页过程中看到的数据是一致的。然后结合 search_after 进行分页。
  • 例子:保证在长时间翻页过程中数据的一致性。

a. 创建 PIT

json 复制代码
POST /my_index/_pit?keep_alive=1m

返回一个 id

b. 使用 PIT 和 search_after 进行查询

json 复制代码
GET /_search
{
  "pit": {
    "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==",
    "keep_alive": "1m"
  },
  "sort": [
    {"@timestamp": "asc"},
    {"_id": "asc"}
  ],
  "size": 100,
  "search_after": [
    1698390400000,
    "o1W6_osB8-dyz-MuPqQ3"
  ]
}

方案总结与对比

方案 适用场景 优点 缺点
from + size 浅分页:用户界面的前几十或几百页数据。例如,网站的商品列表、新闻列表的前几页。 1. 使用简单,易于理解。 2. 支持随机跳页。 1. 深度分页性能极差from 值越大,协调节点需要排序和汇总的结果越多,消耗的内存和CPU也越多。 2. 默认 index.max_result_window 为 10000,限制了其使用深度。
scroll 离线处理:需要从索引中导出全部数据或批量处理所有符合条件的数据。例如,数据迁移、日志分析、全量备份。 1. 适合处理海量数据。 2. 高效,因为后续请求不需要重复查询和排序。 1. 不适用于实时用户请求。 2. 搜索上下文保持需要开销,占用资源。 3. 数据非实时,是基于第一次查询时的快照。
search_after 深度分页的实时查询:用户需要有序地、实时地翻阅大量数据。例如,微博/新闻流的无限下拉、后台系统的审计日志查看。 1. 解决深度分页性能问题,性能恒定。 2. 查询结果是实时的。 3. 不占用大量资源。 1. 不支持随机跳页 ,只能一页一页顺序翻。 2. 需要至少一个唯一性排序字段(通常加上 _id)。 3. 页面结构相对固定(依赖于上一页的结果)。
PIT + search_after 对一致性要求高的深度分页:在分页过程中,不允许因数据变更导致结果重复或丢失。例如,金融交易记录的翻页查询、严格的数据核对任务。 1. 具备 search_after 的所有优点。 2. 提供跨页的一致性视图,避免因数据更新导致的分页混乱。 1. 相比纯 search_after 稍复杂,需要管理 PIT ID。 2. 同样不支持随机跳页。 3. PIT 会占用一定的服务器资源。

核心建议

  1. Top N 或浅层分页 :毫不犹豫地使用 from + size
  2. 数据导出或离线处理 :使用 scroll
  3. 深度分页(最常见) :使用 search_after。这是现代 ES 应用中处理深度分页的标准答案。
  4. 深度分页 + 强一致性要求 :使用 PIT + search_after

记住一个黄金法则:永远不要在生产环境中使用 from + size 来获取超过 10000 条以后的数据

资料获取

大家点赞、收藏、关注、评论啦~

精彩专栏推荐订阅:在下方专栏👇🏻

更多博客与资料可查看👇🏻获取联系方式👇🏻,🍅文末获取开发资源及更多资源博客获取🍅

相关推荐
Wang's Blog13 天前
Elastic Stack梳理: 关联关系处理方案深度解析与工程实践
搜索引擎·es·elastic search
Wang's Blog14 天前
Elastic Stack梳理: 聚合分析核心技术深度解析与最佳实践
elasticsearch·搜索引擎·es·elastic search
qiyongwork16 天前
挣值管理中引入ES——更准确的用时间维度监控项目执行
es·evm·earned value·挣值管理
safestar201217 天前
Elasticsearch分片设计:从数据分布失衡到集群稳定性实战
java·es
safestar201217 天前
Elasticsearch ILM实战:从数据热恋到冷静归档的自动化管理
java·开发语言·jvm·elasticsearch·es
safestar201217 天前
Elasticsearch深度实战:从分布式原理到生产环境踩坑全记录
运维·搜索引擎·全文检索·es
G皮T18 天前
【Elasticsearch】索引别名 aliases
大数据·elasticsearch·搜索引擎·es·索引·索引别名·aliases
ζั͡山 ั͡有扶苏 ั͡✾23 天前
EFK 日志系统搭建完整教程
运维·jenkins·kibana·es·filebeat
ζั͡山 ั͡有扶苏 ั͡✾23 天前
ES日志收集与AI智能分析程序
es·日志收集和报告