首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >整合:Elasticsearch 如何重建成列式指标引擎;存储减少 6.6 倍,查询速度提升 160 倍

整合:Elasticsearch 如何重建成列式指标引擎;存储减少 6.6 倍,查询速度提升 160 倍

作者头像
点火三周
发布2026-07-01 19:05:38
发布2026-07-01 19:05:38
90
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏

整合:Elasticsearch 如何重建成列式指标引擎;存储减少 6.6 倍,查询速度提升 160 倍

亲自动手体验 Elasticsearch:深入探索 Elasticsearch Labs 仓库 中的示例笔记本,开始 免费云试用,或者立即在您的 本地机器 上试用 Elastic。

经过一年对时间序列 数据流 (TSDS) 和 Elasticsearch 查询语言 (ES|QL) 的不懈努力,Elasticsearch 已转型成为一个指标数据存储,其在数据摄入、存储和查询性能方面,与 Prometheus、Mimir 和 ClickHouse 相比,表现持平甚至 更优。

Elasticsearch 存储 OpenTelemetry 指标的每个数据点现在仅需 3.75 字节,相比一年前的 25 字节大幅减少。索引吞吐量提升高达 50%。时间序列查询速度最高可达 160 倍。这就是 TSDS 和 ES|QL 一年工作所带来的成果:一个完全列式化的指标引擎,它能与您的日志、追踪和文档数据在同一平台上存储和查询 OpenTelemetry (OTel) 和 Prometheus 数据。如果您对详细的故事、架构细节和基准测试感兴趣,请阅读 我们如何将 Elasticsearch 重建为领先的列式指标数据存储。

本文将上述工作及背后的深入探究整合到了一处。以下是内容的快速概览。TSDS 是 Elasticsearch 用于指标的索引模式:在索引上启用它后,Elasticsearch 会将每个文档按其时间序列排序存储,将给定系列路由到单个分片,并应用针对指标的压缩,无需手动调优。ES|QL 是 Elasticsearch 的管道式查询语言,用于读取这些数据,并且通过这项工作,它将时间序列视为一等公民数据类型。以下所有内容都围绕着如何使 TSDS 占用更小的空间、存储更快,以及如何让 ES|QL 更高效地查询这些数据。

核心信息很简单:对于 TSDS,Elasticsearch 现在是一个完全列式指标引擎,这与大多数人想象的文档存储有所不同。同一个平台可以存储您的指标、日志、追踪和文档,并且 ES|QL 可以查询所有这些数据。

Elasticsearch 如何将指标存储为列式数据

Elasticsearch 中的列式布局基于 TSDS 自 8.7 版本以来强制执行的四个属性:

  • • 指标名称加上维度名称和值会生成 _tsid,这是每个时间序列的唯一标识符。
  • • 数据按 [_tsid 升序, @timestamp 降序] 排序,因此每个时间序列在磁盘上连续存放,并且维度值会聚类在一起。
  • • 分片路由基于 _tsid,因此给定系列存在于一个分片中。
  • • 支持索引是时间限制的,并且不重叠。

过去一年中的关键变化是停止为每个字段保留单独的倒排索引或 BKD 树,而是将每个字段作为 DocValues(Lucene 的列式存储)存储,并辅以 Doc Value Skippers,后者是轻量级的层次化稀疏索引。这使得磁盘布局端到端地列式化,从而允许查询引擎一次读取一列并进行向量化执行处理。

存储:每个数据点从 25 字节降至 3.75 字节

当大多数数据点都带有独特的维度集时(这在 OTel 和 Prometheus 数据中很常见),每个文档通常只包含一个数据点。这种设置最初每个 OTel 数据点占用 25 字节。以下四项改变使其降至 3.75 字节:

变更项

节省字节数

可用版本

Doc Value Skippers

-10 字节

v9.3

更大的数值编解码块

-2 字节

v9.3

合成 _id

-5 字节

v9.4

序列号截断

-4 字节

v9.4

总计

-21 字节 (25 → 3.75)

  • Doc Value Skippers 替代倒排索引和 BKD 树(-10 字节)。 Doc Value Skipper 是一种分层稀疏索引,它记录文档块的最小值和最大值,因此范围查询可以跳过整个文档块。由于 TSDS 按 _tsid@timestamp 排序,维度值在磁盘上聚类,Skippers 在其上表现良好,没有可测量的查询性能退化。Lucene 级别的机制在 Lucene 10 中的 DocValuesSkippers 如何使范围查询更快 中有详细介绍。自 9.3 版本以来,TSDS 默认启用 Skippers。
  • 合成 _id(-5 字节)。 Elasticsearch 不再为 _id 构建倒排索引,而是从 _tsid@timestamp 派生标识符,并使用段级布隆过滤器进行去重,仅在布隆过滤器命中时才回退到 Doc Values。文档 API 保持不变。其实现,包括布隆过滤器如何保持低误报率,在 Elasticsearch 如何通过合成 _id 和布隆过滤器削减时间序列存储 中有详细说明。在 9.4 版本中默认启用。
  • 序列号截断(-4 字节)。 序列号 (_seq_no) 对于复制和乐观并发控制是必需的,但指标是只追加的,很少使用比较并交换更新。对于 TSDS,一旦全局检查点通过,序列号在段合并期间会被截断,这也消除了未来的合并工作。其权衡以及如何重新选择启用,在 Elasticsearch 如何通过在复制后丢弃序列号将指标存储减少 41% 中有所介绍。在 9.4 版本中普遍可用 (GA)。
  • 更大的数值编解码块(-2 字节)。 在 9.3 版本中,将数值块大小从 128 提高到 512 元素,使得编解码器能够压缩重复序列,例如包含 IP 和 MAC 地址的维度。

索引:原生 OTLP 和 Prometheus 摄入

OTel 和 Prometheus 都以协议缓冲区 (protobuf) 形式发送指标。Elasticsearch 现在可以直接通过原生的 OpenTelemetry Protocol (OTLP) 和 Prometheus remote write 入口点接受这些二进制消息,而无需先将它们转换为批量请求。对于这两种协议,解析二进制数据比解析 JSON 更经济,_tsid 哈希在协调器上每个文档计算一次并在数据节点之间复用,并且维度哈希在一条消息中的多个数据点上分摊。结合 Doc Value Skippers 节省的索引 CPU 和 9.1 版本中添加的合成恢复源,OTel 索引吞吐量提高了高达 50%;由于 Prometheus remote write 复用相同的摄入路径,它也受益于这些优化。OTLP 入口点在 9.3 版本中达到 GA;Prometheus remote write 入口点在 9.4 版本中作为技术预览发布。

使用 ES|QL 查询 Elasticsearch 时间序列指标

列式布局只有在查询引擎以列式方式读取时才能发挥作用。ES|QL 中的 TS 源命令以两级模型运行时间序列查询:每系列一次内部聚合(例如 RATEAVG_OVER_TIME),然后是跨系列的外部聚合(例如 SUMAVG)。由于数据是按 _tsid 顺序到达的,引擎会在获取的指标值列上应用内部函数,直到 _tsid 或时间桶发生变化,所有这些都通过向量化并行执行完成。

代码语言:javascript
复制
TS metrics
| WHERE TRANGE(1d)
| STATS SUM(RATE(search_requests)) BY host.name, TBUCKET(1h)

在此模型之上,还叠加了几项优化:

  • 零拷贝解码 将磁盘上的数据直接读取到计算引擎进行聚合的原始数组中,对重复的 _tsid 和维度值进行行程编码,并对空指标进行 Lucene 级别的过滤。
  • 计数器速率评估 为每个线程分配有序的 _tsid 范围,以便在数据仍按顺序扫描时正确检测重置,并在时间桶边界处插值以获得准确的每桶差值。
  • 滑动窗口 允许聚合跨越多个桶(例如,一个小时的窗口包含五分钟的桶)以平滑噪声,通过两阶段计算以避免重复扫描数据。

综合来看,这些优化使查询延迟比早期的 TSDS 版本提高了 160 倍。TS 和窗口支持在 9.4 版本中达到 GA。

ES|QL:时间序列和指标作为一等公民

ES|QL 中向量化的时间序列引擎(可提供高达 160 倍的查询性能)是您访问列式指标存储的方式。

时间序列支持于 9.2 版本作为技术预览版推出,包含 TS 命令,详见 9.2 ES|QL 更新。9.3 版本扩展了函数库并提高了延迟,详见 Elastic 的指标分析速度提升 5 倍:新增了 PERCENTILE_OVER_TIMESTDDEV_OVER_TIMEVARIANCE_OVER_TIMEDERIV 等用于分布和趋势分析的函数,CLAMP 用于限制嘈杂值,TRANGE 用于时间过滤,以及时间序列聚合上的滑动窗口参数。截至 9.4 版本,TS 命令及其时间序列聚合函数已达到 GA。有关完整参考,请参阅 TS 命令文档 和 时间序列聚合函数文档。

ES|QL 中的指标体验还包括以下三项功能:

  • 原生指数直方图。 exponential_histogram 字段类型直接存储 OTel 指数直方图,因此您可以在查询时以有界误差查询任何百分位数,无需固定桶也无损耗转换。::exponential_histogram 类型转换可以在同一查询中读取旧的 T-Digest 直方图数据。详细信息可在 ES|QL 中原生指数直方图支持 中找到。在 9.4 版本中达到 GA。
  • 时间序列发现。 如果您管理大量指标,仅仅发现和探索时间序列目录中实际存在的数据就可能是一项艰巨的任务。METRICS_INFOTS_INFO 命令会报告在当前查询上下文中实际拥有数据的指标和序列,包括它们的类型、单位和维度,而不是映射声明的所有字段。它们与相同的 TS 执行一起运行,并在数十亿文档上保持响应。有关更多详细信息,请查看 METRICS_INFO 和 TS_INFO 这篇文章。在 9.4 版本中达到 GA。
  • 降采样,完全可查询。 降采样现在提供两种方法:最后值(以实现最大存储节省)和聚合(保留最小值、最大值、总和和计数,并保留计数器重置以实现准确的速率)。两者都支持直方图,并且自 9.4 版本以来,任何基于原始数据构建的 ES|QL 仪表板都可以在降采样的仪表盘上运行而无需更改。有关详细信息,请参阅 最后值与聚合采样。

由于所有这些都是 ES|QL,指标查询可以与语言的其余部分组合使用,包括 LOOKUP JOININLINE STATS,这是仅支持 PromQL 的系统无法做到的。

Prometheus 和 PromQL 兼容性

对于已经构建了十多年 PromQL 查询和 Grafana 仪表板的团队来说,不应该为了获得 Elasticsearch 的所有优势而被迫重写它们。因此,Elasticsearch 现在端到端地支持 Prometheus:它通过 Prometheus remote write 摄入指标,并直接运行 PromQL 查询。

在摄入端,原生的 Prometheus remote write 端点无需适配器即可接受来自 Prometheus 或 Grafana Alloy 的 Snappy 压缩 protobuf,将标签映射到 TSDS 维度,并根据命名约定推断指标类型。其内部机制,从 protobuf 解析到数据流路由,在 Prometheus Remote Write 摄入在 Elasticsearch 中如何工作 中有详细介绍。由于 remote write 复用相同的存储和查询引擎,Prometheus 工作负载也能获得相同的存储和查询性能提升。

PROMQL 源命令直接在 ES|QL 内部运行 PromQL。它不使用单独的引擎:它解析 PromQL 表达式,将函数解析为对应的 ES|QL 等价物(例如,rate 对应 RATEsum 对应 SUM 等),并构建一个 TS 执行计划,因此 PromQL 查询可以获得与原生 ES|QL 相同的向量化并行执行。

代码语言:javascript
复制
1 PROMQL sum(rate(http_requests_total))

在 Kibana 中,该命令会从日期选择器推断 startendstep,结果是一个常规的 ES|QL 表,您可以对其进行过滤、排序并通过 LOOKUP JOIN 进行丰富。完整设计在 在 Elasticsearch 中使用原生 PromQL 支持查询 Prometheus 指标 中有描述。

Prometheus remote write 和 PromQL 均在 9.4 版本中作为技术预览版提供。

Elasticsearch 指标的未来展望

目前有三个活跃的开发领域:

  • TSDS 编解码器改进: 进一步减少每个数据点的字节数,并提供更可配置的布局。
  • 摄入指标的批量处理: 减少格式良好数据的同步开销。
  • 预计算块聚合: Doc Value Skippers 将携带总和和计数,以缩短查询处理时间。

PromQL 覆盖范围和 Prometheus remote write 正在向 GA 迈进。

方向已定:一个平台,一个用于指标的列式引擎,无缝地存储和查询您的指标、日志和追踪。

立即开始 免费云试用,将您的 OTel 或 Prometheus 指标指向它,然后运行一个 TSPROMQL 查询。

本文章中描述的任何功能或特性的发布和时间安排由 Elastic 自行决定。任何目前尚未提供的功能或特性可能不会按时交付或根本不会交付。

常见问题
Elasticsearch 每个指标数据点使用多少字节?

在 9.4 版本中,OTel 指标每个数据点仅需 3.75 字节,相比一年前的 25 字节大幅减少。这 6.6 倍的下降源于 TSDS 的四项改变:Doc Value Skippers、合成 _id、截断的序列号和更大的编解码器块。

Elasticsearch 是一个列式数据存储吗?

对于 TSDS 指标来说,是的。每个指标和维度字段都作为 Lucene Doc Values 存储在自己的文件中,没有单独的倒排索引或 BKD 树。将这种磁盘布局与向量化的 ES|QL 引擎结合,您将获得端到端的列式存储和查询执行。

如何在 ES|QL 中查询时间序列指标?

使用 TS 源命令,自 9.4 版本起已达到 GA。它会运行每个系列内部聚合(RATE、AVG_OVER_TIME 等)和跨系列外部聚合,所有这些都是向量化并行的。例如:TS metrics* | STATS SUM(RATE(search_requests)) BY host.name, TBUCKET(1h)

我可以使用 PromQL 查询 Elasticsearch 指标吗?

可以,其中一种方式是通过 ES|QL 中的 PROMQL 源命令。它解析您的 PromQL,将函数映射到其 ES|QL 等价物,并构建一个 TS 执行计划,因此查询在与所有其他查询相同的引擎上运行。它在 9.4 版本中处于技术预览阶段,我们正在努力实现 PromQL 命令的全面覆盖。您还可以将任何 Prometheus 兼容客户端指向 Elasticsearch,并直接对您现有的指标运行 PromQL。

Elasticsearch 是否原生支持 OpenTelemetry 和 Prometheus 指标?

是的,两者都支持。OTel 指标直接通过 OTLP protobuf 端点(9.3 版本 GA)进入,Prometheus 指标通过原生 Prometheus remote write 端点(9.4 版本技术预览)进入,两种情况都无需适配器或批量转换。OTel 指数直方图也以 exponential_histogram 字段类型(9.4 版本 GA)原样存储,因此您可以在查询时请求任何百分位数。

复制分享

这份内容有多大帮助?

😔 毫无帮助

毫无帮助

😐 有点帮助

有点帮助

😁 非常有帮助

非常有用

报告问题

📡 更多 Elastic & AI 可观测性干货

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 点火三周 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 整合:Elasticsearch 如何重建成列式指标引擎;存储减少 6.6 倍,查询速度提升 160 倍
    • Elasticsearch 如何将指标存储为列式数据
    • 存储:每个数据点从 25 字节降至 3.75 字节
    • 索引:原生 OTLP 和 Prometheus 摄入
    • 使用 ES|QL 查询 Elasticsearch 时间序列指标
    • ES|QL:时间序列和指标作为一等公民
    • Prometheus 和 PromQL 兼容性
    • Elasticsearch 指标的未来展望
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档