比 Prometheus 快 30 倍:我们如何将 Elasticsearch 重构为领先的列式指标数据存储
作者来自 Elastic Kostas Krikellas, Martijn Van Groningen, Nhat Nguyen 及 Felix BarnsteinerElasticsearch 现在以每个数据点 3.75 字节的存储成本保存 OTel 指标并且查询速度最高比 Prometheus 快 30 倍。以下是我们如何重构 TSDS 和 ES|QL。亲自动手体验 Elasticsearch深入探索 Elasticsearch Labs 仓库中的示例 notebooks开始免费的云试用或者立即在你的本地机器上体验 Elastic。Elasticsearch 现在以每个数据点 3.75 字节的存储成本保存 OTel 指标 —— 相比一年前的 25 字节大幅下降 —— 并且相比Prometheus、Mimir和ClickHouse查询速度最高快30 倍存储效率最高提升 2.5 倍。这些提升来自于我们将 TSDS 存储和 ES|QL 计算引擎重构为完全列式的指标引擎同时在此过程中加入了原生 OTel 摄取能力 —— 并且依然保留了 Elasticsearch 同时存储和查询日志、追踪以及任何其他数据的能力。自8.7 版本以来Elasticsearch 一直支持在时间序列数据流TSDS中存储指标。这个方案最初主要聚焦于存储效率提升正如我们之前的一篇博客文章中所解释的那样。不过在存储和查询指标方面其性能仍未达到专用指标系统的水平特别是在存储效率、索引吞吐量和查询延迟方面。在过去一年中我们重新审视了存储层为 OTel 指标优化了数据摄取并通过对时间序列数据引入向量化处理扩展了 ES|QL 计算引擎。与早期版本的 TSDS 相比这些工作在整体性能方面带来了显著提升OTel 指标的存储效率最高提升6.6 倍达到每个数据点 3.75 字节OTel 数据的索引吞吐量最高提升50%查询延迟最高提升160 倍包括极快的计数器速率计算以及时间序列聚合中的窗口支持因此Elasticsearch 已成为领先的列式指标引擎在索引吞吐量方面可与甚至超越 Prometheus、Mimir 和 ClickHouse 等竞争对手并在存储效率方面最高领先2.5 倍在查询性能方面最高领先30 倍。同时它依然保留了存储日志及其他数据的能力并能够完整使用 ES|QL 丰富的查询能力例如 inline stats、lookup join —— 这是其他基于 PromQL 的系统所缺乏的。因此Elasticsearch 可以作为所有用户数据的统一存储与查询引擎在指标和可观测性应用方面无需做出任何妥协。TSDS 的组织方式TSDS 具有以下特性这些特性有助于提升时间序列编解码器的性能并在按时间序列聚合数据点时产生正确结果指标名称以及维度名称和值会被用来计算 [objectObject]这是每个时间序列的唯一标识符。TSDS 会按照[_tsid 升序, timestamp 降序]的顺序进行排序。因此每个时间序列都会按顺序存储在磁盘上较新的数据点优先出现。由于_tsid是基于维度值计算的因此这些维度值在磁盘上也会被聚集存储。分片路由基于_tsid每个_tsid值只会出现在一个分片中。后备索引backing indices是有时间边界的并且它们之间不存在时间重叠。本文其余部分将解释我们如何利用这些特性来提升存储、索引和查询性能。存储优化当可以在单个文档中组合多个指标并共享相同维度值时TSDS 已经能够实现极具竞争力的存储占用最低可达到每个数据点 0.9 字节。然而当大多数数据点都拥有唯一的一组维度时这在 OTel 或 Prometheus 指标中非常常见文档最终只会包含单个数据点。在这种情况下存储成本达到每个数据点 25 字节而专用指标存储系统通常只需要不到 10 字节。为了进一步降低存储占用我们在过去一年中实施了一系列优化使用 doc value skippers 替代倒排索引和 BKD 树默认情况下Elasticsearch 会为所有非指标字段创建倒排索引文本字段或 BKD 树数值字段即timestamp和维度字段。这些索引能够提升包含这些字段过滤条件的查询性能但会显著增加存储开销 —— 实际上会让每个字段的存储占用翻倍。此外这些索引还会在 segment merge 期间被处理从而增加 CPU、内存和存储开销并拖慢整个系统 —— 尤其是在高摄取吞吐量场景下而这正是指标数据的典型特征。Lucene 现已扩展支持 doc value skippers这是一种分层稀疏索引形式用于存储文档块中的最小值和最大值。范围查询可以检查这些最小值和最大值并跳过不在请求范围内的文档块。Skippers 在已排序字段上表现尤其优秀。由于 TSDS 按照[_tsid, timestamp desc]排序因此维度值也会在磁盘上聚集存储。因此可以使用 doc value skippers 替代timestamp和维度字段上的索引从而强化列式布局—— 每个字段存储在独立文件中并且无需为了索引目的重复跟踪每个文档。Doc value skippers 几乎不会带来额外存储开销 —— 用它们替代索引后在 OTel 场景中每个数据点的存储成本从原始的 25 字节减少了10 字节。此外当查询包含时间范围或维度值过滤条件包括前缀和正则表达式时它们在实际运行中的表现也非常出色 —— 在我们的基准测试中用 skippers 替代独立索引后查询性能没有出现明显回退。从9.3 版本开始TSDS 默认启用 doc value skippers。启用合成 ID_id元数据字段也是存储占用的重要来源之一。TSDS 已经扩展支持在 doc values 不再用于复制后对其进行裁剪但倒排索引仍然被保留下来以高效支持基于 id 的 APIGet、Delete、Update。TSDS 的 ID 值是通过组合_tsid和timestamp值生成的这两个字段能够唯一标识每个数据点。由于这些字段已经配置了 doc value skippers因此可以将_id上的倒排索引替换为a从_id值中解析出_tsid和timestamp值以及b分别使用 doc value skippers 来检查匹配项。在指标摄取期间需要特别注意避免昂贵的重复 ID 检查而 segment 级别的 bloom-filters 能够有效控制这部分开销。在指标场景中支持合成 ID 是 Elasticsearch 的首次尝试。这项优化使 OTel 指标每个数据点的存储成本在原始 25 字节基础上进一步减少了5 字节并且没有损失任何功能。从9.4 版本开始TSDS 默认启用合成 ID。经过进一步评估后我们计划将其扩展应用到日志及其他场景中。裁剪序列号序列号被用于复制同时也通过乐观并发控制Optimistic Concurrency Control - OCC在文档修改操作中提供强一致性语义。虽然这些语义适用于某些场景但它们并不适合指标数据因为指标中并发更新非常少而且在数据点具有相同 id 时也没有实际防止并发操作的需求。因此我们决定在 TSDS 的所有 API 中禁用序列号的使用以及 OCC 支持该变更在9.4 版本中生效。这带来了显著的存储减少在 OTel 数据中每个数据点从最初的 25 字节中减少了4 字节。同时由于不再需要倒排索引并且序列号在复制不再需要后会被裁剪从而进一步降低开销。按查询更新和删除操作仍然支持但一致性语义有所减弱。如果某个指标应用仍然认为 OCC 很重要可以通过在相关 TSDS 的 index template 中设置index.disable_sequence_numbers: false来恢复旧行为。使用大数值编码块TSDS 已经使用了一种高级编码器正如之前一篇文章中所解释的那样。该编码器在大多数情况下表现良好但在重复的关键词和数字序列场景中性能较差这会导致包含 IP 和 MAC 地址的维度出现存储膨胀问题。我们发现现有用于识别重复序列的逻辑需要更大的编码块才能发挥良好效果尤其是在序列长度增加时更为明显。经过实验在9.3 版本中将数值块大小从 128 提升到 512 个元素从而在包含 IP 和 MAC 地址维度的 OTel 数据集中每个数据点减少了 2 字节的存储开销。我们也在研发一种更可配置的编码布局允许根据字段类型和基数cardinality对块大小及其他参数进行更灵活的调整。索引吞吐量Elasticsearch 支持通过 bulk 方式进行文档摄取。这个入口长期以来都经过优化以保证宽松性确保所有文档都能被接收。然而这种灵活性会在索引过程中带来额外的处理成本。指标类应用被证明非常适合采用不同的方法来降低这部分开销如下所述。引入 OTLP protobuf 入口OTel 指标和 Prometheus 都已经建立了成熟的指标摄取协议基于 protocol buffers协议缓冲。在过去需要一个转换步骤将收集到的 protobuf 消息转换为 Elasticsearch 可以消费的 bulk 请求。Elasticsearch 最近新增了能够直接接收来自 OTel metrics collector 以及 Prometheus remote write 的消息的端点。与 JSON 解析相比解析和处理这些二进制消息的成本更低同时在_tsid计算中对维度进行 hash 操作可以在同一个 protobuf 消息中的多个数据点之间复用并摊销。此外_tsid在协调节点中每个文档只计算一次然后传递到数据节点用于索引从而避免在每个索引文档上重复执行这一昂贵步骤。这些优化使 OTel 指标的索引吞吐量最高提升约 20%。OTLP 入口在 9.2 版本中以技术预览形式加入并在 9.3 版本中正式 GA。同时我们在9.4 版本中为 Prometheus remote write添加了类似入口技术预览并正在积极扩展以覆盖 OTel 日志和追踪数据。通过 doc value skippers 降低索引 CPU除了显著的存储占用减少之外倒排索引在构建以及 segment merge 过程中也需要大量 CPU 进行处理和重建。使用 doc value skippers 替代这些索引同样可以降低摄取时的 CPU 负载从而带来约 10% 的索引吞吐提升这也是在前述存储收益之外的额外收益。合成 recovery source文档在索引时提供的原始 source 在指标场景中并不会被持久存储。然而 Elasticsearch 仍然需要在复制过程中临时保存它。这一点在9.1 版本发生了变化source 在复制时改为按需合成这被称为 synthetic recovery source。这一机制减少了约 50% 的磁盘 I/O并对指标索引性能带来了显著提升。更多细节可参考相关文章。查询执行将倒排索引替换为 doc value skippers 会使 TSDS 变为纯列式存储布局其中指标和维度字段都以 Lucene doc values 形式存储每个字段都在各自独立的文件中进行编码和压缩。结合 ES|QL 计算引擎的引入其内部使用向量化执行使得在 Elasticsearch 中为指标构建一个完全列式的存储与查询处理引擎成为可能。我们将这一思路推向极致实现了一个列式指标处理引擎在查询性能上能够稳定超越专用指标引擎以及其他列式存储系统。计算引擎中的时间序列集成时间序列处理主要基于对每个时间序列即_tsid应用聚合函数例如 gauge 平均值或 counter 速率。这些部分结果随后会通过第二层函数进行归约以生成按分组维度例如按 host 和 process聚合的结果。可观测性仪表盘正是基于这一执行模型构建的它提供指标随时间变化的汇总视图并支持通过维度值和时间范围过滤来快速深入分析。为了支持这一执行模型我们引入了 TS source 命令提供了一种简单但强大的语法用于执行此类查询它将“每个时间序列的内部聚合函数”和“对前述部分结果的外部聚合”组合在一起。例如以下查询计算过去一天内每个 host 的 search 请求速率的按小时求和TS metrics | WHERE TRANGE(1d) | STATS SUM(RATE(search_requests)) BY TBUCKET(1h), host为了执行该查询计算引擎能够感知数据的存储方式并针对每个_tsid值应用内部聚合函数。由于数据按照_tsid进行了排序时间序列聚合函数会在获取指标值的过程中持续处理直到_tsid发生变化或时间戳进入下一个时间桶为止。这使得这些函数能够在获取到的指标值列上进行向量化执行而维度值只会在_tsid发生变化时被获取一次。第二层聚合函数的计算同样是高效的部分聚合结果被存储在原始类型的数组中并在_tsid值发生变化时进行填充。向量化时间序列聚合执行计算引擎本身具备对并行查询执行的原生支持能够充分利用可用的处理核心。时间序列聚合完全利用这一特性在适用情况下并行处理数据点通过提升 CPU 利用率来降低响应时间。ES|QL 中的时间序列处理在 9.2 版本以技术预览形式引入并在9.4 版本达到正式发布。我们预计所有指标应用都会采用它并从显著提升的查询性能中受益。零拷贝数据解码与加载与通过/searchAPI 执行的聚合相比向量化时间序列处理带来了立竿见影的性能提升某些查询可达8 倍但与竞争性的指标存储相比仍然存在差距。基准测试和性能分析显示在计算引擎中从数据解码到聚合函数执行之间存在过多的数组拷贝。为此引入了以下优化TSDS 的编码器被扩展为可以直接将磁盘上的数据解码到计算引擎用于执行时间序列聚合的块内原始数组中。无需额外拷贝因为计算引擎可以批量读取这些块并按列逐个处理数组。对于在一个块中重复 N 次单一值的情况这些块会被表示为常量块仅包含两个值而不是长度为 N 的数组这是一种内存中的运行长度编码形式。过滤和聚合操作也被扩展以高效处理这些块。这减少了_tsid和维度字段的内存压力与 CPU 开销因为这些值在索引排序后会被聚集存储。对于聚合指标字段中为 null 的文档会在 Lucene 层面直接过滤掉避免在解码并写入块之前进行处理。所有针对时间戳和维度字段的过滤器与正则表达式都会下推到 Lucene由 doc value skippers 高效过滤不匹配的文档。综合这些优化查询执行速度提升超过10 倍与向量化执行带来的 8 倍提升叠加后总体可达 80 倍。这些改进自9.2 版本引入 TS source 命令以来逐步加入并持续优化至今。优化计数器速率计算虽然大多数时间序列聚合都可以轻松并行化执行但累计计数器的速率计算却比较复杂因为它需要按顺序处理所有数据点以检测计数器重置例如主机重启时。为了解决这个问题计算引擎使用_tsid前缀对时间序列进行线程级分片。在设计中我们特别注意为每个线程分配有序的_tsid值范围而不是对_tsid进行哈希分片这样每个线程都可以按顺序扫描磁盘数据同时继续利用高效解码和零拷贝写入块的能力。性能提升非常显著速率计算的性能甚至超过了专用指标存储系统下一节将详细展示这一点。另一个关于累计计数器的有趣问题是当时间桶边界没有数据点时如何正确计算整个时间桶内的计数增长。指标系统通常使用外推法extrapolation将每个时间桶的首尾数据点延伸到边界或计算相邻桶最后一个数据点之间的差值。我们认为可以做得更好通过在每个时间桶的最后一个数据点与下一个桶的第一个数据点之间进行插值来估算边界上的值。然后在每个时间桶的下边界和上边界的插值值之间计算差值从而得到更精确的结果。跨时间桶边界的计数器速率插值滑动窗口支持Elasticsearch 长期以来支持按时间进行分桶聚合但无法将处理窗口扩展到单个时间桶之外。例如当按分钟分桶时如果使用 5 分钟的窗口就可以在更大范围内平滑突发峰值并以更低噪声观察每个时间序列的底层趋势所有时间序列聚合函数都已扩展支持窗口window作为可选参数。当窗口是时间桶的倍数时例如 TBUCKET(5m) 配合 1h 窗口计算引擎会先在与时间桶跨度一致的区间内对数据点进行聚合然后再在窗口范围内合并这些部分结果。这种两阶段处理方式避免了对数据点的重复扫描并实现了中间结果的最大复用从而提升响应速度。窗口支持在 9.3 版本以技术预览形式引入并在9.4 版本达到正式发布。高效的日期时间取整时间序列查询通常包含时间分桶操作。虽然数据点可以轻松分配到小时以下的时间桶中但当桶变大时会涉及时区、夏令时、每月天数不固定等问题。Elasticsearch 具备复杂的日期时间取整逻辑来处理这些特殊情况但在处理时间序列数据时这会带来较高的 CPU 开销。为此计算引擎进行了扩展能够识别哪些场景可以使用更简单的逻辑来将数据点分配到时间桶。例如当桶小于一小时或者时区与夏令时不会影响查询时就会切换为简单的取模运算来进行日期时间取整。这一优化使部分查询的响应时间进一步提升约30%。该改进在9.4 版本中引入。性能评估为了评估我们的方案性能并跟踪其随时间的演进与改进我们重点选择了 OTel 指标作为基准数据因为(a) OpenTelemetry 是行业标准的指标采集方案被所有云厂商广泛采用(b) 它会导致一种 “每个文档一个指标” 的存储布局而这种布局传统上对 Elasticsearch 的性能并不友好。我们依赖 Metricsgenreceiver 来生成数据集。该工具受 TSBS 启发用于模拟 OTel hostmetricreceiver 收集的数据点。我们使用了两个数据集低基数low-cardinality场景100 台主机每 1 秒发送一次指标共计约 14k 条时间序列高基数high-cardinality场景10k 台主机每 10 秒发送一次指标共计约 140 万条时间序列我们在 EC2 单节点部署上进行基准测试低基数和高基数数据集分别使用 c6i.4xlarge 和 c8g.8xlarge 机器。在对比系统方面我们使用了 Prometheusv3.11.1、Mimirv3.0.6以及 ClickHousev26.3.9.8-lts。Prometheus 和 Mimir 具备完善的时间序列处理能力例如计数器速率计算而 ClickHouse 则缺乏此类支持仅能提供近似结果例如无法一致地处理计数器重置。尽管如此我们仍然报告 ClickHouse 的响应时间因为这可以说明当我们将 Elasticsearch 优化为列式查询引擎后即使在其他列式引擎未按时间序列语义处理数据的情况下它仍然能够超越它们。我们尽量为所有系统使用默认配置包括 Elasticsearch不针对特定工作负载进行调优。这有助于理解普通用户缺乏经验或时间进行调优在接入指标数据和搭建仪表盘时的真实体验。我们主要关注单节点运行以降低噪声并确保所有系统都能运行例如 Prometheus 默认不支持多节点部署。Elasticsearch 的性能在节点扩展时具备良好的可扩展性我们计划在后续文章中分享扩展性测试结果。存储效率与索引吞吐量我们在提升存储效率方面的努力取得了显著成果。OTel 指标的性能从每个数据点 25 字节下降到 3.75 字节仅用了一年时间就完成了这一提升。在一个已经针对时间序列高度优化的系统之上还能实现这样的改进这在行业中是非常罕见且令人印象深刻的。存储效率随时间的改进目前的竞争格局看起来是有利的Elasticsearch在存储效率和索引吞吐量方面略优于 Mimir在存储效率方面比 Prometheus 高2.5 倍在索引吞吐量方面也略有优势在存储效率方面比 ClickHouse 高2 倍在索引吞吐量方面高 40%跨系统的存储效率对比跨系统的索引吞吐量对比查询性能新的用于指标处理的列式引擎在实践中证明非常高效。我们使用了基于 gauge 平均值和 counter 速率的混合查询这是最常见且需要不同优化方法的操作。查询区间为4小时数据覆盖每个指标的所有时间序列。ClickHouse 不支持时间序列聚合因此结果具有有限价值且不能直接与 Prometheus 或 Mimir 进行比较这些系统原生支持时间序列处理。我们使用已发布的指南对每个查询进行调整以在尽可能的范围内获得相似结果。目的是展示我们的列式引擎与通用列式存储的对比情况。以下是结果摘要查询类型MimirPrometheusClickHouse †Gauge 平均值最高快 30 倍最高快 30 倍最高快 8 倍Counter 速率最高快 30 倍最高快 30 倍最高快 3.5 倍主机名前缀过滤最高快 5 倍最高快 5 倍最高快 3 倍带窗口的 Gauge 平均值最高快 25 倍最高快 25 倍最高快 4 倍†ClickHouse 缺乏对时间序列聚合和计数器重置检测的原生支持。Gauge 平均值我们对按时间序列计算“每个主机的每小时平均内存利用率”的性能进行了对比评估使用如下查询# PromQL avg by (host.name) (avg_over_time(system.memory.utilization[1h]))# ES|QL TS metrics-hostmetricsreceiver.otel-default | STATS AVG(AVG_OVER_TIME(system.memory.utilization)) BY host.name, TBUCKET(1h)Elasticsearch 在低基数和高基数数据集上都能轻松地比其他系统快最多 30 倍。Gauge 平均值查询性能 —— 低基数Gauge 平均值查询性能 —— 高基数Counter 速率接下来我们对“每个主机按小时计算 CPU 速率平均值”的执行性能进行了对比使用如下查询# PromQL avg by (host.name) (rate(system.cpu.time[1h]))# ES|QL TS metrics-hostmetricsreceiver.otel-default | STATS AVG(RATE(system.cpu.time)) BY host.name, TBUCKET(1h)尽管按时间序列顺序逐点处理数据但 counter 速率性能与 gauge 平均值计算相当相关时间序列的文档数量是上述查询的 6.6 倍。与其他系统相比Elasticsearch 仍然保持显著优势在低基数数据集中比 Mimir 和 Prometheus 快 30 倍在高基数数据集中快 16 倍。Counter 速率查询性能 —— 低基数Counter 速率查询性能 —— 高基数在高基数数据集中Elasticsearch 能在不到 2 秒内处理 50 万条时间序列的 4 小时数据这一点非常令人印象深刻而其他系统则需要超过 30 秒从而导致这类查询的仪表盘变得无响应。ClickHouse 也更慢尽管它没有用于检测计数器重置以及在时间桶之间进行外推/插值计算 delta 的逻辑。主机名前缀过滤接下来我们对基于主机名前缀的过滤性能进行了对比使用如下查询# PromQL avg by (host_name) (avg_over_time(system_cpu_load_average_1m{host_name~host-.*}[5m]))# ES|QL TS metrics-hostmetricsreceiver.otel-default | WHERE host.name LIKE host-* | STATS AVG(AVG_OVER_TIME(system.cpu.load_average.1m)) BY host.name, TBUCKET(5m)尽管将 host.name 上的倒排索引替换为 doc value skipperElasticsearch 仍然能够保持最高 5 倍于其他系统的优势。前缀过滤查询性能 —— 低基数前缀过滤查询性能 —— 高基数带窗口的 Gauge 平均值我们对时间序列聚合在窗口为 90 分钟、时间桶为 30 分钟的情况下进行了性能对比使用如下查询# PromQL avg by (host.name) (avg_over_time(system.memory.utilization[90m]))step30m# ES|QL TS metrics-hostmetricsreceiver.otel-default | STATS AVG(AVG_OVER_TIME(system.memory.utilization, 90m)) BY host.name, TBUCKET(30m)带窗口的 Gauge 平均值 —— 低基数带窗口的 Gauge 平均值 —— 高基数Elasticsearch 在低基数数据集中保持最高 25 倍的优势在高基数数据集中保持最高 8 倍的优势。ClickHouse 的性能落后近 4 倍这说明了我们在窗口查询操作方面方法的高效性。Elasticsearch 指标的未来Elasticsearch 已扩展出指标存储与处理能力在性能上优于 Prometheus、Mimir 和 ClickHouse。我们正在快速推进对 PromQL 和 Prometheus remote write 的支持这些功能在9.4 版本中也作为技术预览提供。这些扩展使熟悉 Prometheus 及相关系统的用户可以将应用迁移到 Elasticsearch —— 无需迁移现有仪表盘。由于 Prometheus 集成复用了本文所述的同一存储与查询引擎因此相同的性能收益也适用于 Prometheus。此外指标既可以用 PromQL 查询也可以用 ES|QL 查询甚至可以在同一个 ES|QL 查询管道中结合使用从而显著增强分析能力远超以往基于 Prometheus 的系统所能实现的范围。在存储效率、索引吞吐量和查询性能方面的改进已经非常显著但我们仍未停止。我们将继续优化时间序列数据的编码器进一步降低每个数据点的字节数。同时还会改进批量指标处理减少同步开销以及对结构良好指标数据而言不必要的冗余处理层。我们还计划更广泛地使用 doc value skippers在数据块级别存储预计算的 sum 和 count 等聚合结果从而在适用情况下跳过数据点加载与处理并采用更高 CPU 友好的分区与分组操作。常见问题什么是列式指标引擎它为什么重要列式指标引擎将每个字段单独存储而不是按行存储然后在查询时只读取所需列。对于时间序列数据这意味着 Elasticsearch 可以分别解码指标值、维度字段和时间戳并在每一列上进行向量化操作。相比行存储这种方式带来更快的聚合速度和更低的存储开销。Elasticsearch 与 Prometheus 在时序指标存储和查询方面如何对比Elasticsearch 在 9.4 版本中将 OTel 指标压缩到每数据点 3.75 字节比 Prometheus 低约 2.5 倍。在查询方面Elasticsearch 在 gauge average 和 counter rate 基准测试中比 Prometheus 和 Mimir 快最高 30 倍。在高基数数据集140 万时间序列中Elasticsearch 在不到 2 秒内处理 4 小时数据而 Prometheus 需要超过 30 秒。什么是 Elasticsearch TSDS什么时候应该使用它TSDStime-series data streams - 时间序列数据流是 Elasticsearch 用于指标与时间序列数据的存储格式。它按_tsid和时间戳排序文档将字段以列式 doc values 存储并使用专用编码器压缩数据。适用于所有指标工作负载尤其是 OpenTelemetry 或 Prometheus 数据对存储效率和查询速度有要求的场景。ES|QL 中的 TS source 命令是什么TS是 ES|QL 的 source 命令在 9.4 版本达到正式发布用于执行时间序列查询采用双层模型先对每个时间序列执行内部聚合如RATE()或AVG_OVER_TIME()再对结果进行外层聚合。计算引擎按时间序列排序执行数据支持向量化与并行处理。例如TS metrics | STATS AVG(RATE(cpu.time)) BY host.name, TBUCKET(1h)。Elasticsearch 如何从每个 OTel 数据点 25 字节降到 3.75 字节在 9.1 到 9.4 版本中通过四项优化实现用 doc value skippers 替代倒排索引减少 10 字节、启用合成 ID减少 5 字节、裁剪序列号减少 4 字节、以及将编码块从 128 提升到 512减少 2 字节。最终在一年内实现约 6.7 倍的存储压缩。Elasticsearch 能否在不迁移仪表盘的情况下替代 PrometheusElasticsearch 支持 Prometheus remote write9.4 技术预览和 PromQL 查询9.4 技术预览。现有 Grafana PromQL 仪表盘只需少量修改即可指向 Elasticsearch。由于 TSDS 存储和 ES|QL 引擎同时支撑 PromQL 和 ES|QL两者都能获得相同性能收益。什么是 doc value skippers为什么对指标很重要doc value skippers 是 Lucene 的结构用于存储文档块的最小值和最大值。在 TSDS 中它们替代了维度字段和timestamp上的倒排索引。这样可以每个数据点减少约 10 字节存储并降低约 10% 的索引 CPU 开销同时在时间范围与维度过滤上没有性能回退。原文https://www.elastic.co/search-labs/blog/elasticsearch-columnar-metrics-engine-30x-faster-prometheus