时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载Grafana Mimir 内置了一套匿名使用统计anonymous usage statistics reporting系统它会周期性地把集群版本、运行环境、关键配置和规模指标等非敏感、非个人可识别的信息上报到远程统计服务器帮助维护者了解开源社区如何部署 Mimir 并决定后续功能与文档的投入方向。本文基于仓库中的官方文档 about-anonymous-usage-statistics-reporting.md 和 pkg/usagestats 源码完整讲解上报了哪些信息、报告如何生成与调度、以及如何通过 CLI 标志或 YAML 配置关闭该功能。读完本文你将能够准确判断 Mimir 集群会对外发送哪些数据并掌握验证上报行为与一键退订的方法。功能定位默认开启、可匿名、可退订官方文档对该功能的定义是Mimir 会可选地、匿名地上报关于正在运行的 Mimir 集群的非敏感、非个人可识别信息。维护者利用这些匿名信息来学习开源社区如何运行 Mimir从而决定团队在下一批功能和文档改进上应该聚焦什么。几个关键结论均来自官方文档与源码默认开启。CLI 标志-usage-stats.enabled的默认值为true这一点在 pkg/usagestats/reporter.go 的RegisterFlags中确认f.BoolVar(cfg.Enabled, usage-stats.enabled, true, Enable anonymous usage reporting.)同时 cmd/mimir/config-descriptor.json 中usage_stats配置块的enabled字段fieldDefaultValue也是true。可退订设置 CLI 标志-usage-stats.enabledfalse或在 YAML 配置中设置usage_stats.enabled: false。上报对象是集群而非个体用户报告中的集群标识是一个随机生成的 UUID不包含任何租户 ID、主机名或其他可定位到具体组织的信息。usage_stats配置块除了enabled之外还有一个installation_mode字段默认值custom支持custom、helm、jsonnet三个取值用于标记该集群是通过哪种方式部署的它会被写入每份报告中。统计服务器与上报节奏当使用统计上报开启时信息会被 Grafana Labs 运行的服务器收集统计端点为https://stats.grafana.org完整上报路径见源码常量defaultStatsServerURL https://stats.grafana.org/mimir-usage-report定义于 pkg/usagestats/reporter.go。从 reporter.go 中的常量可以看出内部节奏常量值含义DefaultReportSendInterval4 小时报告的发送周期即同一份统计每 4 小时汇总上报一次defaultReportCheckInterval1 分钟Reporter 服务检查“是否到了发送时间”的频率defaultCPUUsageSampleInterval1 分钟CPU 使用率采样间隔Reporter 是一个services.Service见 reporter.go 的NewReporter其running主循环做三件事初始化或读取集群种子文件下文详述每分钟检查一次是否到达下一次报告时间若某份报告发送失败会在下一个检查周期重试同一份报告如果失败时间超过一个完整周期time.Since(nextReportAt) reportSendInterval则跳过该份报告直接进入下一轮避免报告积压每分钟采样一次进程 CPU 使用率通过gopsutil的process.CPUPercent取区间内的峰值写入报告的cpu_usage指标。发送本身使用一个超时 5 秒的http.Client以POST application/json形式发送 JSON 报告非 2xx 响应会被记为失败响应体在日志中截断至 128 字节。报告时间如何对齐一个值得注意的细节是getNextReportAt函数reporter.go下一次报告时间不是简单地取“整点 周期”而是以集群种子文件的创建时间为基准计算createdAt ceil((now - createdAt) / interval) * interval。源码注释说明这样做的目的有两个让同一 Mimir 集群的所有副本计算出完全一致的报告时间集群内所有实例对齐同时避免不同集群在同一时刻向统计服务器集中打点。上报了哪些信息官方文档完整列出了开启上报后 Mimir 收集的信息类别。以下按文档分类逐一展开并结合源码指出各字段的实际来源。1. Mimir 集群与版本信息一个唯一的、随机生成的 Mimir 集群标识符如3749b5e2-b727-4107-95ae-172abac27496匿名使用统计上报首次启用、集群标识符被创建的时间戳Mimir 版本如2.3.0构建该二进制所用的 Mimir 分支branch、提交修订revision与 Golang 版本部署 Mimir 所用的安装方式installation mode如helm。源码对应关系报告结构体Reportpkg/usagestats/report.go包含ClusterID、CreatedAt、Versionprom.PrometheusVersion含Version/Revision/Branch/GoVersion、Target、Edition、Mode等字段。版本信息由 pkg/util/version 包在构建时注入buildVersion()见 report.go。安装方式来自-usage-stats.installation-mode配置在 pkg/mimir/modules.go 中通过usagestats.GetString(installation_mode).Set(...)写入。2. 运行环境信息操作系统如linuxCPU 架构如amd64Mimir 的内存占用与 goroutine 数量Mimir 进程的 CPU 使用率。源码对应关系Report.Os/Report.Arch直接取自runtime.GOOS/runtime.GOARCHreport.go。buildMetrics()会输出memstats来自runtime.ReadMemStats的内存细节包括alloc、total_alloc、sys、heap_alloc、heap_inuse、stack_inuse、pause_total_ns、num_gc、gc_cpu_fraction见 report.gonum_goroutineruntime.NumGoroutine()cpu_usageReporter 每分钟采样并取峰值的进程 CPU 百分比recordCPUUsagereporter.go。3. Mimir 配置信息-target参数值例如单体monolithic模式下的all-blocks-storage.backend值例如s3-ingester.ring.replication-factor值例如3-ingester.ring.store值例如memberlist-ingester.out-of-order-time-window的最小值与最大值该值可以按租户覆盖但租户 ID 不会被上报。源码对应关系-target在 pkg/mimir/mimir.go 通过usagestats.SetTarget(t.Cfg.Target.String())写入-blocks-storage.backend在 pkg/mimir/modules.go 写入blocks_storage_backend副本因子与 ring 存储在 Ingester 初始化时写入replicationFactor.Set(int64(cfg.IngesterRing.ReplicationFactor))和ringStoreName.Set(cfg.IngesterRing.KVStore.Store)pkg/ingester/ingester.go对应统计名ingester_replication_factor与ingester_ring_storeingester.goOOO 时间窗口的 min/max 见下一节的 Ingester 周期更新逻辑。4. 集群规模信息Ingester 侧内存中的 series 数量活跃activeseries 数量拥有内存 series 的租户数量开启了乱序out-of-order摄入的租户数量已摄入的 sample 与 exemplar 数量。Querier 侧不跟踪任何实际请求或查询内容按 API 端点类型拆分的请求数量包括Remote read、Instant query、Range query、Exemplars query、Labels query、Series query、Metadata query、Cardinality analysis query。源码对应关系Ingester 的统计名定义于 pkg/ingester/ingester.gomemorySeriesStatsName ingester_inmemory_series activeSeriesStatsName ingester_active_series memoryTenantsStatsName ingester_inmemory_tenants appendedSamplesStatsName ingester_appended_samples appendedExemplarsStatsName ingester_appended_exemplars tenantsWithOutOfOrderEnabledStatName ingester_ooo_enabled_tenants minOutOfOrderTimeWindowSecondsStatName ingester_ooo_min_window maxOutOfOrderTimeWindowSecondsStatName ingester_ooo_max_window这些 Int 统计由 Ingester 周期性更新updateUsageStats遍历所有租户 TSDB统计Head().NumSeries()只计至少 1 条 series 的租户、active series 数以及按租户读取OutOfOrderTimeWindow配置后聚合出的全局最小/最大窗口秒数pkg/ingester/ingester_metrics_update.go——租户 ID 只用于本地聚合不会出现在报告中与文档“tenant ID is not shared”的描述一致。更新间隔为DefaultReportSendInterval / 10即 24 秒保证 4 小时报告周期内的数值基本反映周期末状态。Querier 侧的端点计数由一个通用的RequestsMiddlewarepkg/usagestats/middleware.go实现——它只是一个对每个请求执行counter.Inc(1)的 HTTP 中间件。各端点的挂载点见 pkg/api/handlers.go例如remoteReadStats : usagestats.NewRequestsMiddleware(querier_remote_read_requests) instantQueryStats : usagestats.NewRequestsMiddleware(querier_instant_query_requests) rangeQueryStats : usagestats.NewRequestsMiddleware(querier_range_query_requests) // ... 还有 exemplars / labels / series / metadata / cardinality / formatting/api/v1/query、/api/v1/query_range、/api/v1/labels、/api/v1/series、/api/v1/metadata、/api/v1/cardinality/*等路由分别被对应中间件包裹只记录请求次数不读取请求体。官方文档同时注明维护者承诺保持这份被跟踪信息列表随时间更新并且任何变化都会通过 CHANGELOG 和 release notes 报告。源码级原理集群种子、统计变量与报告结构集群种子文件UUID 从哪里来报告中的集群 ID 不是每次进程启动重新生成而是持久化在对象存储中。pkg/usagestats/seed.go 实现了这一机制种子文件名为mimir_cluster_seed.json上传到对象存储中 Mimir 内部保留前缀下bucket.NewPrefixedBucketClient(bucketClient, bucket.MimirInternalsPrefix)见 reporter.go文件内容是 JSON{UID: 随机 UUID, created_at: 时间戳}ClusterSeed结构seed.go由于集群中多个副本可能并发创建种子文件源码引入了 5 分钟的“最小稳定期”clusterSeedFileMinStability 5 * time.Minute读取到的种子必须创建满 5 分钟才会被采用在尝试写入前先做带抖动的随机等待0~5 分钟降低多副本撞车概率写入后仍会循环等待稳定期以应对其他副本并发创建。这意味着只要对象存储不变Mimir 集群的匿名身份就是稳定的而“首次启用时间戳”就是该文件的创建时间即文档中列出的第二项信息。基于 expvar 的统计变量体系Mimir 用一个轻量的全局统计变量注册表来收集各模块上报的值见 pkg/usagestats/stats.go所有统计变量统一挂在expvar下前缀为github.com/grafana/mimir/提供GetInt/GetString/GetFloat固定值型与GetCounter累计型四类访问器。Counter内部维护total原子 int64 累加与rate速率在报告构建时调用updateRate()算出周期速率后reset()归零因此 Ingester 的 sample/exemplar 摄入量等以“周期内累计 速率”形式上报buildMetrics()report.go通过expvar.Do遍历所有带该前缀的变量除target、edition、mode三个被提升到报告根层的保留键之外全部放入报告的metrics字段。这个设计让 Ingester、API 层等模块只需调用usagestats.GetInt(...)/GetCounter(...)即可“顺手”上报无需与 Reporter 产生直接依赖。报告 JSON 结构buildReportreport.go生成的最终 JSON 结构为{ clusterID: 3749b5e2-b727-4107-95ae-172abac27496, createdAt: 2024-01-01T00:00:00Z, interval: 2024-01-01T04:00:00Z, intervalPeriod: 14400, target: all, version: { version: 2.3.0, revision: ..., branch: ..., goVersion: go1.xx }, os: linux, arch: amd64, edition: oss, mode: classic, metrics: { memstats: { alloc: 0, heap_alloc: 0, ...: ... }, num_goroutine: 123, cpu_usage: 5.2, ingester_inmemory_series: 100000, ingester_appended_samples: { total: 123456, rate: 8.5 }, querier_range_query_requests: { total: 234, rate: 0.16 }, blocks_storage_backend: s3, installation_mode: helm, ingester_replication_factor: 3, ingester_ring_store: memberlist, ingester_ooo_min_window: 1800, ingester_ooo_max_window: 1800 } }其中mode字段区分经典架构classic与 ingest storage 架构ingest_storage后者在 pkg/mimir/modules.go 中通过usagestats.SetMode(usagestats.ModeIngestStorage)设置edition默认为ossstats.go。失败处理与可观测性Reporter 自身暴露了三个 Prometheus 指标可用于在本地验证上报行为reporter.gocortex_usage_stats_report_sends_total尝试发送的总次数cortex_usage_stats_report_sends_failed_total发送失败的总次数cortex_usage_stats_report_sends_latency_seconds发送延迟直方图。发送失败时 Reporter 会在下一个 1 分钟检查周期重试同一份报告若某份报告长期发送失败导致落后超过一个周期则记录一条 Info 日志并跳到下一周期。此外Mimir 启动时若拿到集群种子会打印usage stats reporter initialized日志并附带cluster_id可用于在对象存储中核对种子文件。关闭匿名使用统计上报官方文档建议“如果可能请保持该功能开启”帮助社区更好地理解 Mimir 的真实部署形态如果确实需要退出有以下两种方式二者等价均对应usage_stats.enabled配置项CLI 标志方式mimir -targetall -usage-stats.enabledfalseYAML 配置方式usage_stats: enabled: false设置为false后UsageStatsReporter服务不会启动进程不再向统计服务器发送任何数据对象存储中的种子文件如果已存在会保持原状不影响数据读写它位于 Mimir 内部保留前缀下与租户数据块隔离。验证与测试依据仓库中有多组测试覆盖了该机制的行为可作为实现事实的交叉验证pkg/usagestats/reporter_test.go验证报告调度、发送与重试行为pkg/usagestats/seed_test.go验证集群种子文件的创建、稳定期等待与损坏重建pkg/usagestats/stats_test.go 与 report_test.go验证统计变量与报告构建逻辑pkg/ingester/ingester_test.go断言 Ingester 各统计值内存 series、活跃 series、租户数、sample/exemplar 计数、OOO 租户数与 min/max 窗口与预期一致。小结Mimir 的匿名使用统计上报是一套默认开启的轻量遥测机制每 4 小时生成一份包含集群 UUID、版本/构建信息、运行环境OS、架构、内存、goroutine、CPU、关键配置target、存储后端、副本因子、ring 存储、OOO 窗口 min/max以及规模数据Ingester 内存 series/租户/摄入量Querier 按端点类型拆分的请求数的 JSON 报告经https://stats.grafana.org/mimir-usage-report端点上报。其集群身份由对象存储中的mimir_cluster_seed.json稳定承载统计采集基于expvar全局变量与 HTTP 中间件实现。如需退出只需设置-usage-stats.enabledfalse或 YAML 中的usage_stats.enabled: false。赞分享时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载相关推荐Grafana Pyroscope 匿名使用统计上报收集内容、底层机制与关闭方法Grafana Pyroscope 匿名使用统计上报收集内容、底层机制与关闭方法 导读 Grafana Pyroscope 默认会向远程统计服务器上报匿名的可观测性性能剖析后端运维观测JuiceFS 匿名用量上报Usage Tracking机制解析数据字段、上报原理与 --no-usage-report 关闭指南JuiceFS 匿名用量上报Usage Tracking机制解析数据字段、上报原理与 no usage report 关闭指南 JuiceFS 客户端默认云原生容器运行时Fleet 使用统计Usage Statistics数据上报内容、实现原理与关闭方法Fleet 使用统计Usage Statistics数据上报内容、实现原理与关闭方法 Fleet 服务器会周期性地向 Fleet Device Manag后端前端企业应用运维网络安全上一篇3分钟永久备份你的QQ空间GetQzonehistory数据归档终极指南下一篇3分钟永久备份QQ空间GetQzonehistory让青春记忆永不丢失创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考