news 2026/9/16 14:54:09

Scrutiny 数据降采样(Downsampling)机制解析:InfluxDB 多级分桶保留策略与自动聚合任务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scrutiny 数据降采样(Downsampling)机制解析:InfluxDB 多级分桶保留策略与自动聚合任务

Scrutiny 数据降采样(Downsampling)机制解析:InfluxDB 多级分桶保留策略与自动聚合任务

【免费下载链接】scrutinyHard Drive S.M.A.R.T Monitoring, Historical Trends & Real World Failure Thresholds项目地址: https://gitcode.com/GitHub_Trending/sc/scrutiny

Scrutiny 作为一款硬盘 S.M.A.R.T 监控与历史趋势分析工具,会持续采集 S.M.A.R.T 属性、自检结果、温度与磁盘容量等时序数据,若不加控制,InfluxDB 数据库将无限膨胀。本文围绕 docs/DOWNSAMPLING.md 展开,完整讲解 Scrutiny 内建的四级降采样(downsampling)体系:每个 bucket 的保留期、聚合范围与窗口、cron 调度,以及底层 Flux 任务脚本与查询侧的分桶路由逻辑。读完本文,你将能理解 Scrutiny 如何在"短期精确"与"长期可趋势分析"之间取得平衡,并掌握通过retention_policy配置、InfluxDB Task 与分桶命名约定来控制数据生命周期的完整方案。

为什么要降采样:短期要精确,长期只要趋势

Scrutiny 的 collector 会周期性地向 InfluxDB 写入大量数据,包括:

  • S.M.A.R.T 属性数据(smart)
  • S.M.A.R.T 自检数据(smart test)
  • 温度数据(temp)
  • 磁盘容量/使用率等指标(disk metrics)

这些数据在短期内必须精确——你需要看到"此刻这块盘的温度是多少、累计通电时间是多少";但做长期趋势分析时,单个数据点并不重要,真正有价值的是聚合结果,例如"过去一年里通电时间大致以什么速度增长""温度的季节性变化"。

如果保留所有原始数据点,数据库会无界增长;如果直接丢弃旧数据,又无法进行跨月、跨年的趋势对比。Scrutiny 的解决方案是:按调度自动对旧数据进行降采样(downsample),用聚合数据替代原始数据,并对聚合后的 bucket 设置不同的保留期限,从而在数据库体积与历史数据可用性之间取得平衡。

从源码看,这一整套机制由后端仓库层(scrutiny_repository.go)在首次启动时自动初始化:EnsureBuckets负责创建各级 bucket 并设置保留规则,EnsureTasks负责在 InfluxDB 中注册周期性的降采样 Task,二者都在 NewScrutinyRepository 初始化流程中被调用,因此对用户来说几乎是"零配置"的。

四层 bucket 体系与保留期

Scrutiny 基于 InfluxDB 2.x 的 bucket 体系实现降采样,围绕配置项web.influxdb.bucket(默认主 bucket 名为metrics)派生出一组带后缀的派生 bucket。完整的分桶与调度参数如下表(摘自原文档):

Bucket 名称保留期降采样范围降采样聚合窗口降采样 Cron说明
metrics15 天-2w -1w1w每周日凌晨 1:00主 bucket,接收 collector 写入的原始数据
metrics_weekly9 周-2mo -1mo1mo每月 1 日凌晨 1:30周聚合数据
metrics_monthly25 个月-2y -1y1y每年 1 月 1 日凌晨 2:00月聚合数据
metrics_yearly永久---年聚合数据,无限期保留

上表中的保留期与调度参数在源码中均有对应常量与硬编码值:

  • 保留期常量定义于 scrutiny_repository.go:RETENTION_PERIOD_15_DAYS_IN_SECONDS = 1_296_000(15 天)、RETENTION_PERIOD_9_WEEKS_IN_SECONDS = 5_443_200(9 周)、RETENTION_PERIOD_25_MONTHS_IN_SECONDS = 65_318_400(25 个月)。
  • 三个降采样 Task 的 cron 分别注册为0 1 * * 030 1 1 * *0 2 1 1 *,任务名分别为tsk-weekly-aggrtsk-monthly-aggrtsk-yearly-aggr,见 scrutiny_repository_tasks.go。

值得注意的是:所有 bucket 名称都基于web.influxdb.bucket动态生成(例如主 bucket 为metrics时,派生 bucket 为metrics_weeklymetrics_monthlymetrics_yearly),见EnsureBuckets中的fmt.Sprintf("%s_weekly", ...)模式(scrutiny_repository.go)。如果你自定义了 bucket 名,派生 bucket 会随之改名。

retention_policy 配置项的作用

EnsureBuckets中有一段关键逻辑:只有当配置项web.influxdb.retention_policytrue时,才会为 bucket 设置保留规则(scrutiny_repository.go)。对应配置位于 example.scrutiny.yaml 的web.influxdb段落:

web: influxdb: host: 0.0.0.0 port: 8086 retention_policy: true

源码注释给出了该配置的用途:在测试环境中,可以将其设为false,这样就能写入带旧时间戳的数据、并手动触发降采样脚本来验证行为;而生产环境应当保持true,让 InfluxDB 自动按保留期清理过期数据。此外,EnsureBuckets对已存在的 bucket 也会主动校正其保留规则(UpdateBucket),确保与配置保持一致。

降采样如何执行:InfluxDB Task 与 Flux 脚本

降采样不是由 Scrutiny 进程本身完成,而是注册为InfluxDB 2.x 的 Task(定时任务)EnsureTasks在每次启动时检查三个任务是否存在:不存在则创建,已存在且 Flux 脚本与当前生成的脚本不一致则更新(scrutiny_repository_tasks.go)。这意味着升级 Scrutiny 后,降采样脚本会自动同步,无需手动维护 InfluxDB 侧的任务。

实际的 Flux 脚本由DownsampleScript方法生成(scrutiny_repository_tasks.go),其核心参数随聚合级别切换:

聚合级别sourceBucketdestBucketrangeStartrangeEndaggWindow
weeklymetricsmetrics_weekly-2w-1w1w
monthlymetrics_weeklymetrics_monthly-2mo-1mo1mo
yearlymetrics_monthlymetrics_yearly-2y-1y1y

以 weekly 任务为例,实际注册到 InfluxDB 的 Flux 脚本如下(与单元测试 scrutiny_repository_tasks_test.go 中的断言完全一致):

option task = { name: "tsk-weekly-aggr", cron: "0 1 * * 0", } sourceBucket = "metrics" rangeStart = -2w rangeEnd = -1w aggWindow = 1w destBucket = "metrics_weekly" destOrg = "scrutiny" from(bucket: sourceBucket) |> range(start: rangeStart, stop: rangeEnd) |> filter(fn: (r) => r["_measurement"] == "smart" ) |> group(columns: ["device_wwn", "_field"]) |> aggregateWindow(every: aggWindow, fn: last, createEmpty: false) |> to(bucket: destBucket, org: destOrg) from(bucket: sourceBucket) |> range(start: rangeStart, stop: rangeEnd) |> filter(fn: (r) => r["_measurement"] == "temp") |> group(columns: ["device_wwn"]) |> toInt() |> aggregateWindow(fn: mean, every: aggWindow, createEmpty: false) |> set(key: "_measurement", value: "temp") |> set(key: "_field", value: "temp") |> to(bucket: destBucket, org: destOrg)

这段脚本揭示了两个重要的设计细节:

  1. 降采样范围刻意滞后一个周期:例如 weekly 任务处理的是-2w-1w的数据,而不是最近一周。这是为了保证上一周期的数据已经完整写入,避免把"正在写入的窗口"聚合进去,确保聚合结果的完整性。
  2. 不同数据类型使用不同的聚合函数:S.M.A.R.T 属性(smartmeasurement)按device_wwn_field分组后使用last聚合——因为 S.M.A.R.T 属性多为累计值(如通电时间、重映射扇区数),取最后一个值才正确;温度数据(tempmeasurement)则先toInt()再使用mean聚合——取一段时间内的平均温度更有趋势意义。源码中有一处 TODO 也提到,last聚合未来可能会被更精确的表示方式替代(scrutiny_repository_tasks.go 的注释中保留了更复杂的 Flux 草案:对 string/bool 类型取last、对 int/float 类型取mean后再union)。

不同时间尺度的数据点分布:5 个月与 5 年

理解了"范围滞后 + 窗口聚合 + 分桶保留"之后,就能推算任一时刻各级 bucket 中每个磁盘的数据点数量。

运行 5 个月后的数据点分布

假设主 bucket 每 7 天写入一批数据(collector 默认每天运行一次),经过 5 个月后,单个磁盘在各 bucket 中的数据点大致如下(原文档表格):

Bucket 名称数据点数量说明
metrics157 个每日数据点 + 最多 7 个待处理数据点 + 1 个缓冲数据点
metrics_weekly94 个已聚合的周数据点 + 4 个待处理数据点 + 1 个缓冲数据点
metrics_monthly33 个已聚合的月数据点
metrics_yearly0尚未有年聚合数据

运行 5 年后的数据点分布

5 年后,各级 bucket 中的数据点分布如下(原文档表格,原文档中该表的具体数值未展开,以-占位,仅示意各级 bucket 仍按各自保留期与聚合周期运转):

Bucket 名称数据点数量说明
metrics-原始数据按 15 天保留期滚动淘汰
metrics_weekly-周聚合数据按 9 周保留期滚动淘汰
metrics_monthly-月聚合数据按 25 个月保留期滚动淘汰
metrics_yearly-年聚合数据永久保留

可以看到,这套体系的核心思想是:越新的数据精度越高、保留期越短;越旧的数据精度越低、保留期越长(直至永久)。15 天的原始数据足够支撑短期精确查询,而年聚合数据则可无限期支撑"这台盘 5 年前的通电时间/温度水平"这类长期对比。

查询侧的分桶路由:数据从哪来

降采样体系的另一面是查询侧如何正确地"从正确的 bucket 取数据"。Scrutiny 在后端维护了一套 duration key 到 bucket 名称与时间范围的映射(scrutiny_repository.go):

duration key对应 bucket查询时间范围嵌套查询的 bucket 集合
weekmetrics-1w~now()metrics
monthmetrics_weekly-1mo~-1wmetrics+metrics_weekly
yearmetrics_monthly-1y~-1mometrics+metrics_weekly+metrics_monthly
forevermetrics_yearly-10y~-1y全部四个 bucket

lookupBucketName/lookupDuration/lookupNestedDurationKeys三个方法共同决定了查询行为:

  • 主数据查询GetSummary):直接对metricsmetrics_weeklymetrics_monthlymetrics_yearly四个 bucket 同时发起查询,取每个字段的last()值后union排序,从而在任意时刻拿到"最新已知值"(scrutiny_repository.go)。
  • 温度历史查询GetSmartTemperatureHistory):通过aggregateTempQuery生成 Flux,按 duration key 递归地查询嵌套 bucket,例如forever会同时对四个 bucket 查询并union,再统一按 1 小时窗口做mean聚合后输出(scrutiny_repository_temperature.go)。

这套"按时间尺度路由到不同 bucket"的机制,配合降采样 Task,构成了完整的数据生命周期闭环:写入端只有metrics,读取端按时间范围透明地跨 bucket 读取,聚合与淘汰则由 InfluxDB Task 与保留规则自动完成。

验证与测试:降采样脚本的正确性保障

降采样脚本由大量单元测试守护,可直接在仓库中查阅:

  • scrutiny_repository_tasks_test.go:Test_DownsampleScript_WeeklyTest_DownsampleScript_MonthlyTest_DownsampleScript_Yearly分别断言三个聚合级别生成的完整 Flux 脚本与期望输出逐字符一致(使用 mock 配置固定web.influxdb.bucket=metricsweb.influxdb.org=scrutiny)。
  • scrutiny_repository_temperature_test.go:Test_aggregateTempQuery_Week/Month/Year/Forever验证温度历史查询在 week、month、year、forever 四种时间尺度下的分桶路由与 Flux 生成逻辑。

这些测试同时起到了"文档化"的作用:如果你想知道某次升级后降采样脚本到底变成了什么样,运行go test ./webapp/backend/pkg/database/...或直接阅读测试中的断言字符串即可。

运维实践要点

综合原文档与源码实现,使用与排查降采样机制时有以下几个关键点:

  1. 保留期与调度均不可通过 YAML 配置:bucket 保留期、Task cron 都在源码中硬编码,scrutiny.yaml中与降采样直接相关的只有web.influxdb.retention_policy(以及web.influxdb.bucketweb.influxdb.org这两个影响 bucket 命名与组织归属的配置项)。collector 的采集频率可通过COLLECTOR_CRON_SCHEDULE环境变量调整(见 rootfs/etc/cron.d/scrutiny),但降采样 Task 本身不可配置。
  2. InfluxDB Task 在首次启动时自动注册:无需手动创建;如果手动删除了任务,重启 web 容器即可重建。任务名固定为tsk-weekly-aggrtsk-monthly-aggrtsk-yearly-aggr
  3. 生产环境保持retention_policy: true:否则 bucket 不会设置保留规则,原始数据不会被自动清理,数据库仍会无界增长。
  4. 排查数据缺失时注意时间滞后:weekly/monthly/yearly 任务的聚合范围分别滞后 1 周/1 月/1 年,刚部署完成时,派生 bucket 中不会有数据,这是正常现象,需要等待首个聚合周期结束。
  5. 手动验证降采样:在测试环境(retention_policy: false)中写入带旧时间戳的数据后,可手动执行 InfluxDB 侧的 Task 或直接运行生成的 Flux 脚本来验证聚合结果。

通过理解这套"多级分桶 + 滞后窗口聚合 + 分级保留"的设计,你可以清楚地回答"Scrutiny 的数据到底存在哪、会保留多久、何时被聚合"这三个问题,也能够在自定义 bucket 名、调整部署架构或排查历史趋势数据异常时,快速定位到正确的配置与源码位置。

【免费下载链接】scrutinyHard Drive S.M.A.R.T Monitoring, Historical Trends & Real World Failure Thresholds项目地址: https://gitcode.com/GitHub_Trending/sc/scrutiny

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 14:53:59

OpenClaw 跑微信 ClawBot:Kimi2.5 的 Key 用 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 14:51:45

STM32电导率仪设计:正弦波激励与DFT信号处理全解析

简介:一款基于STM32的电导率测量仪完整设计资料,面向电子、自动化、仪器仪表及计算机相关专业的毕设、课设和项目初期验证。项目以STM32F429为主控,外接电导率信号处理模块,设计正弦波驱动、滤波、放大与电压转置电路,…

作者头像 李华
网站建设 2026/9/16 14:46:13

Flink实时推荐系统实战:从行为流接入到相似度计算与链路调优

简介:基于Flink实现的商品实时推荐系统源码包,面向大数据流计算与推荐系统开发者,完整演示了从日志采集、热度统计到个性化推荐的生产级实现。系统依托Flink实时计算商品热度并写入Redis缓存,同时将用户画像与行为记录存入HBase&a…

作者头像 李华