本文将介绍我们 Elasticsearch 时间序列数据产品中最重要的存储改进,并深入探讨我们预计系统在存储效率方面表现更好的场景和更差的场景。
背景
Elasticsearch 最近对存储和查询时间序列数据提供了更好的支持。存储效率一直是我们的主要关注领域,许多项目都取得了重大成果,与在标准索引中保存数据相比,可以节省高达 60-80% 的存储空间。在某些情况下,我们的系统可以实现低于每个数据点 1 字节的存储效率,与最先进的专业 TSDB 系统展开正面竞争。让我们来看看时间序列数据存储效率的最新改进。
Elasticsearch 时间序列数据中的存储改进
合成源
默认情况下,Elasticsearch 将原始 JSON 文档主体存储在 _source 字段中。对于指标而言,这种重复会对存储造成不利影响,并且收益递减,因为指标通常通过不使用此字段的聚合查询进行检查。为了缓解这个问题,我们引入了 合成 _source,它可以根据文档字段中存储的数据按需重建原始 _source
的一种形式。需要注意的是,支持的字段类型数量有限,并且 _source
合成比从存储字段中检索它要慢。尽管如此,这些限制在很大程度上与主要依赖于关键字、数字、布尔值和 IP 字段,并使用不考虑 _source
内容的聚合查询的指标数据集无关。我们正在单独努力消除这些限制,以使合成源适用于任何映射。
存储优势是立竿见影的:启用合成源可以将 时间序列数据流 (TSDS) 索引的大小减少 40-60%(有关性能评估,请参见下文)。因此,自 TSDS 发布(v.8.7)以来,它就默认使用合成源。
专用编解码器
TSDB 系统大量使用专用编解码器,这些编解码器利用记录的指标的时序排序来减少每个数据点的字节数。我们的产品扩展了标准的 Lucene 编解码器,支持 游程长度编码、差分编码(二阶导数)、GCD 和 XOR 编码以用于数字值。编解码器在 Lucene 段级别指定,因此旧索引在索引新数据时可以利用最新的编解码器。
为了提高这些压缩技术的效率,索引会根据计算出的 标识符(所有 维度字段)进行排序(升序),然后按时间戳排序(降序,以返回每个时间序列的最新数据点)。这样,维度字段(主要是关键字)就可以使用游程长度编码进行有效压缩,而指标的数字值则按时间序列进行聚类并按时间排序。由于大多数时间序列随时间推移变化缓慢,偶尔会出现峰值,并且 Elasticsearch 依赖于 Lucene 的垂直分区 存储引擎,因此这种方法最大程度地减少了连续存储数据之间的差异并提高了存储效率。
元数据修剪
_id
字段是用于唯一标识 Elasticsearch 中每个文档的元数据字段。它对指标应用程序的价值有限,因为时间序列分析依赖于跨时间聚合值的查询,而不是检查单个指标值。为此,TSDS 会修剪存储的值,但会保留此字段的反向索引以继续支持文档检索查询。这会导致存储空间减少 10-20%,而不会损失任何功能。
生命周期集成
TSDS 可以与数据生命周期管理机制集成,即 ILM 和 数据流生命周期。这些工具可以自动删除旧索引,而 ILM 还支持随着索引的陈旧而将其移动到存储成本更低的层(例如,使用旋转磁盘或归档云存储)。生命周期管理降低了存储成本,不会影响对频繁访问的指标的查询性能,并且用户参与度最低。
降采样
在许多指标应用程序中,最好仅在短期内保留细粒度数据(例如,过去一周的每分钟数据),并且可以接受增加旧数据的粒度以节省存储空间(例如,过去一个月的每小时数据,过去两年的每日数据)。降采样 会将原始指标数据替换为在可配置的时间段内(例如,每小时或每日)预聚合指标的 统计表示。这可以提高存储效率(因为降采样索引的大小只是原始指标索引的一小部分)和查询性能(因为聚合查询会扫描预聚合的结果,而不是根据需要对原始数据进行计算)。
降采样与 ILM 和 DSL 集成,这些工具可以自动应用降采样,并允许随着数据陈旧而使用不同分辨率的降采样数据。
TSDS 存储效率的测试结果
TSDS 存储收益
我们通过每晚的 基准测试跟踪性能,包括存储使用情况和效率。 TSDB 跟踪(请参阅磁盘使用情况可视化)显示了我们存储改进的影响。接下来,我们将介绍 TSDS 发布前的存储使用情况、TSDS 正式发布后的改进情况以及当前状态。
TSDB 跟踪的数据集(k8s 指标)有九个维度字段,每个文档平均包含 33 个字段(指标和维度)。索引包含一天的指标,超过 116,633,696 个文档。
在 ES 8.7 版本之前,索引 TSDB 跟踪的数据集需要 56.9GB 的存储空间。通过按元数据字段、时间戳字段、维度字段和指标字段细分存储使用情况,可以深入了解存储使用情况,这一点很有趣。
字段名称 | 百分比 |
---|---|
_id | 5.1% |
_seq_no | 1.4% |
_source | 78.0% |
@timestamp | 1.31% |
维度字段 | 2.4% |
指标字段 | 5.1% |
其他字段 | 9.8% |
_source 元数据字段是迄今为止对存储空间占用量贡献最大的字段。如前所述,合成源是我们指标工作为提高存储效率而推动的改进之一。这在 ES 8.7 中很明显,ES 8.7 默认情况下对 TSDS 使用合成源。在这种情况下,存储空间占用量降至 6.5GB——存储效率提高了 8.75 倍。按字段类型细分
字段名称 | 百分比 |
---|---|
_id | 18.7% |
_seq_no | 14.1% |
@timestamp | 12.6% |
维度字段 | 3.6% |
指标字段 | 12.0% |
其他字段 | 50.4% |
改进的原因是 _source
不再存储,以及应用索引排序以按顺序存储来自同一时间序列的指标,从而提高了标准 Lucene 编解码器的效率。
使用 ES 8.13.4 索引 TSDB 跟踪的数据集占用 4.5GB 的存储空间——进一步提高了 44%。按字段类型细分如下:
字段名称 | 百分比 |
---|---|
_id | 12.2% |
_seq_no | 20.6% |
@timestamp | 14.0% |
维度字段 | 1.6% |
指标字段 | 6.7% |
其他字段 | 58.6% |
与 8.7.0 版本相比,这是一个重大的改进。最新版本的改进主要得益于以下几个因素:_id
字段占用更少的存储空间(其存储值会被截断),同时维度字段和其他数值字段使用最新的时间序列编解码器进行更高效的压缩。
现在,大部分存储空间都归因于“其他字段”,即提供类似于维度上下文的字段,但不用于计算用于索引排序的标识符,因此它们的压缩效率不如维度字段。
降采样存储增益
根据降采样间隔,降采样以牺牲查询分辨率为代价来换取存储增益。使用 1 分钟间隔对 TSDB 跟踪数据集中的指标(以每 10 秒收集一次指标)进行降采样,会产生一个 748MB 的索引——6 倍的改进。缺点是指标会以每分钟的粒度进行预聚合,因此无法再检查单个指标记录或跨子分钟间隔(例如,每 5 秒)进行聚合。最重要的是,预计算统计数据(最小值、最大值、总和、计数、平均值)的聚合结果与根据原始数据计算的结果相同,因此降采样不会导致任何精度损失。
如果可以容忍较低的分辨率,并且使用每小时间隔对指标进行降采样,则生成的降采样索引将仅使用 56MB 的存储空间。请注意,改进幅度为13.3 倍,低于从每分钟降采样间隔切换到每小时降采样间隔时预期的 60 倍。这是由于所有索引都需要存储每个段的额外元数据,这是一个恒定的开销,随着索引大小减小而变得更加明显。
综合考虑
下图显示了存储效率在不同版本中的演变情况,以及降采样可以提供的额外节省。请注意,纵轴采用对数刻度。
总的来说,我们在过去几个版本中,为我们的指标产品实现了12.5 倍的存储效率提升。如果我们通过降采样以减少存储空间为代价来换取分桶分辨率,那么这甚至可以达到1000 倍或更高。
TSDS 配置提示
在本节中,我们将探讨在考虑存储效率的情况下配置 TSDS 的最佳实践。
每个文档优先使用多个指标
虽然 Elasticsearch 使用垂直分区来分别存储每个字段,但字段仍然在文档中逻辑上分组。由于指标共享包含在同一文档中的维度,因此当我们在每个索引文档中包含尽可能多的指标时,维度和元数据的存储开销会得到更好的摊销。另一方面,在每个文档中存储单个指标及其关联的维度,会最大化维度和元数据的开销,并导致存储膨胀。
更具体地说,我们使用合成数据集来量化每个文档中指标数量的影响。当我们在每个索引文档中包含所有指标(20 个)时,TSDS 使用的存储空间低至每个数据点 0.9 字节——接近最先进的、专用指标系统(每个数据点 0.7 字节)的性能,这些系统缺乏 Elasticsearch 用于非结构化数据的丰富索引和查询功能。相反,当每个索引文档包含单个指标时,TSDS 需要每个数据点 20 字节,存储空间大幅增加。因此,将尽可能多的指标分组到每个索引文档中,共享相同的维度值,这样做是有益的。
修剪不必要的维度
当涉及到每个指标的时间序列数量(即维度基数的乘积)达到数百万甚至更多时,Elasticsearch 架构使我们的指标产品能够比竞争系统更好地扩展,并且性能成本可控。尽管如此,维度确实会占用相当大的空间,并且高基数会降低我们用于 TSDS 的压缩技术的效率。因此,仔细考虑哪些字段包含在指标的索引文档中,并积极地将维度修剪到仪表板和故障排除所需的最小集合,这一点非常重要。
这里一个有趣的例子是可观察性映射,其中包含一个 IP 字段,结果发现该字段包含多达 16 个主机 IP(v4、v6)地址。它对存储空间和索引吞吐量都产生了重大影响,而且很少使用。用机器标签替换它导致了可观的存储改进,而没有损失可调试性。
使用生命周期管理
ILM 促进将较旧的、不常访问的数据移动到更便宜的存储选项,并且 ILM 和 数据流生命周期 都可以处理随着时间推移删除指标数据。这种完全自动化的方式降低了存储成本,而无需更改索引映射或配置,因此强烈建议使用。
此外,值得考虑随着数据年龄的增长,通过降采样来换取指标分辨率。假设降低分桶分辨率对于较旧的数据是可以接受的(在实践中很常见,因为例如检查数月前的数据以每分钟的粒度进行检查的情况很少见),那么这种技术可以带来大量的存储优势,并使仪表板响应速度更快。
后续步骤
在过去几年中,我们已经显著改进了指标的存储空间占用。我们打算将这些优化应用到指标以外的其他数据类型,特别是日志数据。虽然一些功能是特定于指标的,例如降采样,但我们仍然希望使用特定于日志的索引配置来实现 2-4 倍的存储空间减少。
尽管减少了所有 Elasticsearch 索引所需的元数据字段的存储开销,但我们计划更积极地修剪它们。_id
和 _seq_no
字段是不错的候选对象。此外,还有机会应用更高级的索引技术,例如 稀疏索引,用于时间戳和其他支持范围查询的字段。
如果可以接受少量存储空间损失,降采样机制对于改进查询性能具有巨大潜力。一个想法是在重叠的时间段上支持多个降采样分辨率(例如,原始、每小时和每天),查询引擎会自动为每个查询选择最合适的解决方案。这将允许用户指定降采样以匹配其仪表板时间缩放并使其更具响应性,以及在索引后几分钟内启动降采样。它还将解锁保留原始数据以及降采样数据的功能,可能会使用更慢/更便宜的存储层。
试一试
- 如果您还没有账户,请注册 Elastic Cloud
- 配置一个 TSDS 并用它来存储和查询指标
- 探索 降采样 以查看它是否适合您的用例
- 享受存储节省