ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Grafana Pyroscope Compactor 架构与配置完全指南:块压缩、Split-and-Merge 算法与磁盘估算

Grafana Pyroscope Compactor 架构与配置完全指南:块压缩、Split-and-Merge 算法与磁盘估算 Grafana Pyroscope Compactor 架构与配置完全指南块压缩、Split-and-Merge 算法与磁盘估算【免费下载链接】pyroscopeContinuous Profiling Platform. Debug performance issues down to a single line of code项目地址: https://gitcode.com/GitHub_Trending/py/pyroscopeGrafana Pyroscope 是一个持续性能分析Continuous Profiling平台其存储层采用块block为单位组织 profiling 数据。本文聚焦 Pyroscope v1 架构中的compactor压缩器组件系统讲解它如何通过垂直/水平压缩合并块、去重复制样本、降低长期存储成本并提升查询性能深入剖析 split-and-merge 分片合并算法、compactor 分片sharding、块删除机制并给出完整的配置参数、磁盘空间估算与调优建议。读完本文你将掌握 compactor 的完整工作原理能够针对大租户场景正确配置压缩并发、分片数、分组数、压缩作业排序与磁盘容量。提示compactor 是 Pyroscopev1 架构组件。v2 架构中的对等组件是 compaction worker本文不展开介绍。Compactor 的职责查询加速与存储瘦身compactor 是一个**无状态stateless**组件在 Pyroscope 集群中承担两项核心职责合并块并去重将某个租户tenant的多个块压缩为单个、经过优化的更大块。合并过程会去重 chunk数据块并缩小索引体积从而降低存储成本同时查询时扫描的块数量更少查询速度也因此提升。维护每租户的 bucket indexbucket index 是 querier 和 store-gateway 发现存储中新增块与被删除块的依据compactor 负责及时更新它保证查询路径看到一致的块视图。从源码结构看compactor 的核心实现位于 pkg/compactor 目录MultitenantCompactorcompactor.go是顶层服务负责周期性地扫描存储桶、发现租户并驱动压缩BucketCompactor负责单个租户的块压缩执行BlocksCleanerblocks_cleaner.go负责块的软删除与硬删除。整个目录还包含split_merge_*系列文件对应下文将详细介绍的 split-and-merge 算法。压缩的工作原理垂直压缩与水平压缩压缩按租户独立进行compactor 以可配置的固定间隔周期运行。压缩分为两个阶段垂直压缩Vertical compaction垂直压缩将 ingester 上传的、属于同一时间范围默认 1 小时的某个租户的所有块合并为一个块同时去重因复制replication而写入 N 个块的重复样本。其效果是把单一时间范围内的块数量从ingester 数量降为每个租户一个块。这也解释了为何配置中存在-compactor.first-level-compaction-wait-period默认 25 分钟——它让 compactor 在压缩一级块之前等待一段时间减少部分 ingester 尚未上传块就启动压缩的情形见 compactor.go 中的 flag 说明。水平压缩Horizontal compaction水平压缩在垂直压缩之后触发将时间范围相邻的几个块合并为更大的块。水平压缩不会改变块 chunk 的总大小但它能显著缩小索引index以及 store-gateway 在内存中维护的 index-header 体积——因为块数量变少了每个块需要维护的索引条目总量下降。下图直观展示了两种压缩的差异垂直压缩合并并去重同一租户时间上重叠的块水平压缩合并时间上相邻的块。压缩运行周期与重试源码佐证MultitenantCompactor.running()compactor.go显示compactor 启动后会先立即执行一次初始压缩随后按-compactor.compaction-interval默认 30 分钟带 5% 抖动周期性触发compactUsers。每次运行中compactor 会从存储桶发现租户列表bucket.ListUsers并随机打乱顺序以降低多副本同时压缩同一租户的概率compactor.go通过shardingStrategy.compactorOwnUser判断该租户是否属于本实例的 shardcompactor.go对归属本实例的租户调用compactUserWithRetries按-compactor.compaction-retries默认 3 次重试失败的压缩。扩容策略垂直扩容与水平扩容压缩按租户进行因此可以对拥有大租户的集群进行针对性调优配置同时涵盖垂直与水平两个维度的扩展垂直扩容Vertical scaling-compactor.compaction-concurrency配置单个 compactor 实例内并行的压缩任务数上限每个压缩任务占用一个 CPU 核默认值为 1见 compactor.go。增大该值可让单个实例利用更多 CPU 并发压缩不同租户/作业。水平扩容Horizontal scaling默认情况下任意 compactor 都可以压缩任意租户的块。当启用 compactor shuffle sharding 后——即把-compactor.compactor-tenant-shard-size或其 YAML 配置compactor_tenant_shard_size设置为大于 0 且小于可用 compactor 数量的值——只有指定数量的 compactor 才有资格为给定租户压缩块。该限值是按租户生效的见 limits.go 中 flag 说明0 to disable the limit and use all compactors适合将大租户隔离到独立 compactor 组、避免大租户压缩任务拖累小租户。此外-compactor.compaction-retries默认 3控制单次压缩运行内失败压缩的重试次数-compactor.max-compaction-time默认 1 小时限制单个租户在单次压缩周期内启动新压缩的最大时间避免单个租户耗尽整个压缩周期多租户场景尤其有用见 compactor.go。压缩算法Split-and-MergePyroscope 采用名为split-and-merge的分层压缩算法。从设计上看该算法克服了时序数据库TSDB索引的天然限制避免了大租户在任何压缩阶段出现压缩块无限增长的问题。split-and-merge 是分阶段split与合并merge的两阶段过程默认配置下 split 阶段被禁用-compactor.split-and-merge-shards默认值为 0见 limits.go。Split 阶段在第一个压缩级别例如2h范围执行 split 时compactor 把所有源块划分为N个组由-compactor.split-groups控制。对每个组compactor 压缩这些块但不是输出单个结果块而是输出M个块由-compactor.split-and-merge-shards控制即所谓的split blocks拆分块。每个 split block 只包含属于M个 shard 中某一 shard 的 series 子集。split 阶段结束时compactor 产生N × M个块每个块在自身的meta.json中记录其所属 shard。Merge 阶段compactor 对每个 shard 的 split blocks 执行合并把给定 shard 的全部N个 split block 压缩到一起块数量从N × M降为M。对于给定压缩时间范围最终每个 shard 对应一个压缩后的块。merge 随后继续在其余配置的压缩时间范围例如1h和4h上运行合并属于同一 shard 的块。下图展示了-compactor.split-and-merge-shards2时的完整流程源块被两个 compactor 分别拆成 2 个 shard再由另外两个 compactor 合并为压缩块。参数与权衡该策略面向大租户集群。Mshard 数通过-compactor.split-and-merge-shards按租户配置可根据各租户的 series 数量调整租户的 series 越多配置的 shard 数可以越大从而提升压缩并行度并让每个 shard 的压缩块大小保持可控。Nsplit 组数通过-compactor.split-groups按租户调整默认值为 1见 limits.go。增大N会在 split 阶段产生更多、块数更少的压缩作业让多个 compactor 能并行处理这些作业、更快完成 split但代价是 split 阶段产生更多中间块这些中间块只能在后续 merge 阶段被消减。需要特别注意如果压缩进行中修改了-compactor.split-and-merge-shards该变更只影响尚未 split 的块已 split 的块在 merge 时仍使用原始配置——原始配置记录在每个 split block 的meta.json中。因此修改 shard 数需要等待现有 split 块全部合并完成才完全生效。split 与 merge 均可水平扩展不冲突、不重叠的作业会被并行执行。从源码看splitAndMergeShardingStrategy.ownJobcompactor.go先确认租户归属再对作业的ShardingKey()哈希后判断本实例是否拥有该作业从而保证每个作业只被一个 compactor 执行SplitAndMergePlanner.Plansplit_merge_planner.go则校验待压缩块都落在最大时间范围内作为分组逻辑正确性的双重检查。此外split_and_merge_compactor.go、split_merge_grouper.go与对应的_test.go文件共同构成了这一算法的实现与验证。Compactor 分片Sharding与哈希环compactor 会对压缩作业分片——无论是来自单个租户还是多个租户的作业。单个租户的压缩也可以被拆分成多个作业、由多个 compactor 实例并行处理。当 compactor 实例池扩容或缩容时租户与作业会在可用实例之间自动重新分片resharding无需人工干预。Compactor 分片基于哈希环hash ring实现启动时compactor 生成随机 token 并注册到 compactor hash ring每个实例在 ring 中拥有 512 个 token见 compactor_ring.go运行期间它以-compactor.compaction-interval为周期扫描存储桶发现租户列表并只为 hash 落在本实例 token 范围内的租户压缩块compactorOwnUser通过ring.ShuffleShard(userID, shardSize)判断实例是否属于该租户的 shard见 compactor.go。若要配置 compactors 的哈希环请参考 configuring memberlist。ring 相关配置项集中在compactor.ring.*前缀下例如-compactor.ring.wait-active-instance-timeout默认 10 分钟等待 compactor 在 ring 中变为 ACTIVE等compactor_ring.go。启动时等待哈希环稳定集群冷启动或同时扩容 2 个及以上 compactor 实例时各实例启动时刻可能略有差异导致每个 compactor 基于不同状态的哈希环执行首次压缩。这不是错误状态但可能低效多个实例可能几乎同时开始压缩同一个租户。为缓解该问题可以配置 compactor 在启动时等待 ring 稳定。ring 稳定的判定标准是在-compactor.ring.wait-stability-min-duration时间内没有实例加入或离开哈希环。等待总时长上限由-compactor.ring.wait-stability-max-duration控制默认 5 分钟。当 compactor 结束等待ring 已稳定或达到最大等待时间后即正常启动。若-compactor.ring.wait-stability-min-duration为默认值0则禁用等待 ring 稳定的功能。对应的源码实现在 compactor.go当WaitStabilityMinDuration 0时调用ring.WaitRingStability若超过最大等待时间仍未稳定则以 WARN 日志proceeding anyway继续启动。压缩作业的排序策略compactor 通过-compactor.compaction-jobs-orderflag或对应 YAML 配置compaction_jobs_order配置压缩作业的执行顺序。该排序决定了哪些压缩作业优先执行。支持以下取值定义见 job_sorting.gosmallest-range-oldest-blocks-first默认优先处理最小时间范围、最旧块。例如压缩范围为1h, 4h, 8h时compactor 先压缩1h范围的块并优先处理其中最旧的块全部1h范围压缩完成后再进入2h范围最后是8h范围。源码注释job_sorting.go给出的设计理由是更小的范围能更早完成样本去重而更旧的块更可能完整不存在尚未上传的缺失块。所有split 作业会被移到工作队列最前面因为完成某时间范围内的全部 split 作业可以解除对应 merge 作业的阻塞merge 作业只有在同一时间范围没有 split 作业时才会生成从而让更多 compactor 有机会并行工作。newest-blocks-first优先处理最新的时间范围无论其压缩级别如何。例如压缩范围为1h, 4h, 8h时compactor 先压缩最新的块一直到8h范围再处理更旧的块。该策略假定最新块被查询得最频繁适合 compactor 落后lagging behind时优先补齐近期数据。两种排序的实现分别位于sortJobsBySmallestRangeOldestBlocksFirst与sortJobsByNewestBlocksFirstjob_sorting.go并通过GetJobsOrderFunction在启动时注入到MultitenantCompactor.jobsOrder若配置了不支持的取值compactor 会启动失败并报unsupported compaction order错误compactor.go。块的删除机制软删除与硬删除压缩成功后原始块会从存储中删除。但删除不是立即执行的而是两阶段过程标记删除软删除原始块先被标记为待删除硬删除块被标记为待删除的时间超过-compactor.deletion-delay默认 12 小时见 compactor.go后才从存储中真正删除。compactor 同时负责标记块与硬删除两项工作。软删除基于存放在桶内块位置的一个小型deletion-mark.json文件实现。BlocksCleaner在清理周期中读取 bucket index 中的BlockDeletionMarks筛选出标记时间超过删除延迟的块并执行硬删除blocks_cleaner.go当-compactor.deletion-delay设为 0 时块会被立即删除但 flag 帮助信息明确警告立即删除块可能导致查询失败。软删除机制的意义在于它给 querier 和 store-gateway 留出发现新压缩块的时间窗口再删除原始块。如果原始块被立即硬删除涉及压缩块的某些查询可能会临时失败或返回部分结果。与之配套-compactor.cleanup-interval默认 15 分钟控制块清理与维护、以及 bucket index 更新的频率-compactor.cleanup-concurrency默认 20控制并行执行清理的租户数。Compactor 磁盘空间估算compactor 需要从桶下载块到本地磁盘也需要把压缩后的块暂存到本地磁盘后再上传回桶。最大的租户可能需要大量磁盘空间。假设max_compaction_range_blocks_size表示最长-compactor.block-ranges周期内最大租户的总块大小那么估算最小所需磁盘空间的表达式为compactor.compaction-concurrency * max_compaction_range_blocks_size * 2即compaction-concurrency个并发压缩任务每个任务同时需要下载中的原始块与待上传的压缩块两份空间因此乘 2。-compactor.block-ranges是压缩时间范围列表默认值为1h, 2h, 8hcompactor.go且要求每个范围都能被前一个范围整除、第一个范围能被最大块时长整除校验逻辑见 compactor.go。在规划节点磁盘时应按最大并发数 × 最大租户最大范围块大小 × 2 预留容量并为临时目录-compactor.data-dir默认./data-compactor提供足够空间——该目录不需要在重启之间持久化compactor.go。Compactor 配置速查compactor 配置分为两部分compactor 自身配置块与limits 配置块完整参数清单可参考 reference configuration parameters 文档中的compactor与limits两个区块。以下是本文涉及的关键参数汇总默认值均来自当前仓库源码参数flag / YAML默认值作用-compactor.compaction-interval/compaction_interval30m压缩运行周期启动后先立即执行一次-compactor.compaction-concurrency/compaction_concurrency1单实例最大并发压缩任务数每个任务占用一个 CPU 核-compactor.compaction-retries/compaction_retries3单次压缩运行内失败压缩的重试次数-compactor.first-level-compaction-wait-period25m压缩一级块前的等待时间降低 ingester 未上传完就开始压缩的概率-compactor.max-compaction-time/max_compaction_time1h单租户在单次压缩周期内启动新压缩的最大时间0 表示禁用-compactor.block-ranges/block_ranges1h, 2h, 8h压缩时间范围列表需可逐级整除-compactor.deletion-delay/deletion_delay12h块被标记删除后到硬删除的延迟0 表示立即删除有查询失败风险-compactor.cleanup-interval/cleanup_interval15m块清理、维护与 bucket index 更新频率-compactor.cleanup-concurrency/cleanup_concurrency20并行执行清理的租户数-compactor.compaction-jobs-order/compaction_jobs_ordersmallest-range-oldest-blocks-first压缩作业执行顺序另一取值newest-blocks-first-compactor.compactor-tenant-shard-size/compactor_tenant_shard_size0单个租户可用的 compactor 数量上限0 表示使用全部 compactor-compactor.split-and-merge-shards/compactor_split_and_merge_shards0split-and-merge 的 shard 数0 表示禁用 split 阶段-compactor.split-groups/compactor_split_groups1split 阶段源块分组数-compactor.ring.wait-stability-min-duration0启动时等待 ring 稳定的最短时间0 表示禁用等待-compactor.ring.wait-stability-max-duration5m启动时等待 ring 稳定的最大时间超时后照常启动-compactor.data-dir/data_dir./data-compactor压缩临时目录无需持久化-compactor.block-sync-concurrency8下载块与上传压缩块的并发数-compactor.meta-sync-concurrency20同步块 meta 文件的并发数-compactor.max-opening-blocks-concurrency16压缩前打开块的 goroutine 数-compactor.enabled-tenants/disabled-tenants空允许/禁止压缩的租户白名单/黑名单受分片约束典型大租户调优示例以下 YAML 片段展示了为大型租户集群配置 compactor 的典型方式compactor与overrides分属不同配置区块具体挂载位置以 reference configuration parameters 为准compactor: # 单实例最多并行 4 个压缩任务占用 4 核 compaction_concurrency: 4 # 每 15 分钟扫描一次存储桶并执行压缩 compaction_interval: 15m # 压缩范围 1h → 2h → 8h block_ranges: - 1h - 2h - 8h # 块标记删除后等待 24 小时再硬删除 deletion_delay: 24h # 压缩作业排序优先小范围、最旧块 compaction_jobs_order: smallest-range-oldest-blocks-first sharding_ring: # 启动时等待 ring 稳定 1 分钟最多 5 分钟 wait_stability_min_duration: 1m wait_stability_max_duration: 5m overrides: big-tenant: # 该租户允许 3 个 compactor 参与压缩shuffle sharding compactor_tenant_shard_size: 3 # 按 series 规模配置 8 个 shard提升并行度 compactor_split_and_merge_shards: 8 # 4 组 split产生更多可并行的小作业 compactor_split_groups: 4总结compactor 是 Pyroscope 长期存储链路上让数据更少、查询更快的关键组件垂直压缩去重复制样本、水平压缩缩减索引体积split-and-merge 算法则让超大租户的压缩可以横向扩展到多实例并行。在生产环境中建议按照租户规模动态调整-compactor.split-and-merge-shards与-compactor.split-groups结合 shuffle sharding 隔离大租户、利用-compactor.compaction-jobs-order控制作业优先级并按并发数 × 最大租户最大范围块大小 × 2预留磁盘。所有关键参数与默认值均可在 pkg/compactor/compactor.go 与 pkg/validation/limits.go 中核对相关算法实现与测试可进一步阅读 pkg/compactor 目录下的split_merge_*系列文件。【免费下载链接】pyroscopeContinuous Profiling Platform. Debug performance issues down to a single line of code项目地址: https://gitcode.com/GitHub_Trending/py/pyroscope创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表