菜单
开源

Grafana Pyroscope 压缩器

压缩器通过合并块来提高查询性能并减少长期存储使用。

压缩器负责以下功能:

  • 将给定租户的多个块压缩成一个经过优化的更大块。这可以去除块的重复项并减小索引大小,从而降低存储成本。查询更少的块会更快,因此它也提高了查询速度。
  • 保持每个租户的存储桶索引更新。存储桶索引由查询器存储网关用于发现存储中的新块和已删除块。

压缩器是无状态的。

压缩工作原理

压缩按租户进行。

压缩器定期运行,间隔可配置。

垂直压缩将摄取器上传的同一时间范围(默认为 1 小时范围)内给定租户的所有块合并成一个块。它还对由于复制而最初写入 N 个块的样本进行去重。垂直压缩将单个时间范围内块的数量从摄取器的数量减少到每个租户一个块。

水平压缩在垂直压缩后触发。它将几个相邻时间范围的块压缩成一个更大的块。水平压缩后,相关块块的总大小不变。水平压缩可以显著减小索引和存储网关在内存中保留的索引头的大小。

Compactor - horizontal and vertical compaction

扩展

压缩可以针对具有大型租户的集群进行调整。配置指定了压缩器在按租户进行压缩时的垂直和水平扩展方式。

  • 垂直扩展
    设置 -compactor.compaction-concurrency 配置单个压缩器实例中运行的最大并发压缩数。每个压缩使用一个 CPU 核心。
  • 水平扩展
    默认情况下,任何 Grafana Pyroscope 压缩器都可以压缩租户块。当您通过将 -compactor.compactor-tenant-shard-size(或其相应的 YAML 配置选项)设置为大于 0 且小于可用压缩器数量的值来启用压缩器随机分片时,只有指定数量的压缩器才有资格压缩给定租户的块。

压缩算法

Pyroscope 使用一种名为“分割与合并”(split-and-merge)的复杂压缩算法。

从设计上讲,“分割与合并”算法克服了时序数据库 (TSDB) 的索引限制,并避免了在任何压缩阶段,对于非常大的租户,压缩块无限增长的情况。

这种压缩策略是两阶段的过程:分割(split)和合并(merge)。默认配置禁用了分割阶段。

在分割阶段(第一级压缩,例如 2h),压缩器将所有源块划分为 N 个 (-compactor.split-groups) 组。对于每个组,压缩器会压缩这些块,但不是生成一个结果块,而是输出 M 个 (-compactor.split-and-merge-shards) 块,称为分割块。每个分割块仅包含 M 个分片中属于给定分片的时间序列子集。在分割阶段结束时,压缩器会生成 N * M 个块,并在块的 meta.json 文件中引用其各自的分片。

压缩器合并每个分片的分割块。这将压缩给定分片的所有 N 个分割块。合并将块的数量从 N * M 减少到 M。对于给定的压缩时间范围,每个 M 个分片将有一个压缩块。

Compactor - split-and-merge compaction strategy

合并接下来会在其他配置的压缩时间范围内运行,例如 1 小时和 4 小时。它会压缩属于同一分片的块。

此策略适用于具有大型租户的集群。分片数量 M 可以使用 -compactor.split-and-merge-shards 按租户配置,并根据每个租户的时间序列数量进行调整。租户的时间序列越多,您可以增加配置的分片数量。这样做可以提高压缩并行度,并将每个分片的压缩块大小控制在可接受范围内。

分割组的数量 N 也可以使用 -compactor.split-groups 选项按租户进行调整。增加此值会在分割阶段产生更多块数量较少的压缩作业。这使得多个压缩器可以处理这些作业,并更快地完成分割阶段。但是,增加此值也会在分割阶段生成更多中间块,这些块只会在后续的合并阶段减少。

如果在压缩期间更改 -compactor.split-and-merge-shards 的配置,更改将仅影响尚未分割的块的压缩。已分割的块在合并时将使用原始配置。原始配置存储在每个分割块的 meta.json 文件中。

分割和合并可以进行水平扩展。非冲突和不重叠的作业将并行执行。

压缩器分片

压缩器会对压缩作业进行分片,这些作业可能来自单个租户或多个租户。单个租户的压缩可以分割并由多个压缩器实例处理。

无论压缩器池是增长还是缩小,租户和作业都会在可用的压缩器实例之间重新分片,无需任何手动干预。

压缩器分片使用哈希环。在启动时,压缩器生成随机令牌并注册到压缩器哈希环。运行时,它会按照 -compactor.compaction-interval 定义的间隔定期扫描存储桶,以发现存储中的租户列表,并为哈希与实例自身在哈希环中分配的令牌范围匹配的每个租户压缩块。

要配置压缩器的哈希环,请参阅配置 Memberlist

启动时等待稳定的哈希环

集群冷启动或同时增加两个或更多压缩器实例可能导致每个新压缩器实例在略微不同的时间启动。然后,每个压缩器会根据哈希环的不同状态运行其首次压缩。这并非错误条件,但可能效率低下,因为多个压缩器实例可能在几乎同一时间开始压缩同一租户。

为缓解此问题,可以将压缩器配置为在启动时等待稳定的哈希环。如果在至少 -compactor.ring.wait-stability-min-duration 的时间内未向哈希环添加或从哈希环移除任何实例,则认为哈希环稳定。压缩器等待的最大时间由标志 -compactor.ring.wait-stability-max-duration(或相应的 YAML 配置选项)控制。一旦压缩器完成等待,无论是由于环已稳定还是已达到最大等待时间,它都将正常启动。

-compactor.ring.wait-stability-min-duration 的默认值 0 会禁用等待环稳定。

压缩作业顺序

压缩器允许通过 -compactor.compaction-jobs-order 标志(或其相应的 YAML 配置选项)配置压缩作业的顺序。配置的顺序定义了应该首先执行哪些压缩作业。支持以下 -compactor.compaction-jobs-order 值:

  • 最小范围-最旧块优先 (default)

    此顺序优先处理最小范围的最旧块。

    例如,对于压缩范围 1h, 4h, 8h,压缩器将首先压缩 1h 范围内的块,并在其中优先处理最旧的块。一旦 1h 范围内的所有块都已压缩,它将转到 2h 范围,最后转到 8h 范围。

    所有分割作业都会移到工作队列的前面,因为完成给定时间范围内的所有分割作业会解除对合并作业的阻塞。

  • 最新块优先

    此顺序优先处理最新的时间范围,无论其压缩级别如何。

    例如,对于压缩范围 1h, 4h, 8h,压缩器首先压缩最新的块(直到 8h 范围),然后转到更旧的块。此策略有利于最新的块,假设它们被查询的频率最高。

块删除

成功压缩后,原始块将从存储中删除。块删除不是即时的;它遵循一个两步过程:

  1. 原始块被标记为删除;这是软删除
  2. 块被标记删除的时间超过可配置的 -compactor.deletion-delay 后,该块将从存储中删除;这是硬删除

压缩器负责块标记和硬删除。软删除基于存储在存储桶中块位置的小文件 deletion-mark.json

软删除机制让查询器和存储网关有时间在新压缩块被删除之前发现新的压缩块。如果原始块立即被硬删除,一些涉及压缩块的查询可能会暂时失败或返回部分结果。

压缩器磁盘使用

压缩器需要从存储桶下载块到本地磁盘,并且压缩器需要先将压缩块存储到本地磁盘,然后再将其上传到存储桶。最大的租户可能需要大量磁盘空间。

假设 max_compaction_range_blocks_size 是在最长的 -compactor.block-ranges 期间最大租户的总块大小,估算所需最小磁盘空间的表达式为

compactor.compaction-concurrency * max_compaction_range_blocks_size * 2

压缩器配置

有关压缩相关配置的详细信息,请参阅压缩器块部分和限制块部分。