Mimir 用作冷热指标池需对齐 Go 服务写入路径、租户隔离与存储后端:Go 服务 remote_write 必须带 X-Scope-OrgID header;limits.yaml 需配置 ingestion_rate 和 max_global_series_per_user;对象存储 backend 禁用 filesystem,统一使用 S3/GCS 并确保所有组件共享相同配置。

直接用 Mimir 当冷热指标池,不是“配一下就行”,而是得把 Go 服务的 Prometheus 指标写入路径、Mimir 的租户隔离、存储后端三者对齐。否则数据进不去、查不到、或混租户爆炸。
Go 服务必须带 X-Scope-OrgID 写入 remote_write
Mimir 不认 Prometheus 默认的 remote_write;它强制按租户(tenant)分片,所有写入请求必须带 X-Scope-OrgID HTTP header,否则直接 400 或静默丢弃。
- 在 Go 服务里配置 Prometheus
remote_write时,不能只写 URL:http://mimir-distributor:9095/api/v1/push,还得显式加 header - 用
prometheus.NewPusher不行——它不支持自定义 header;得用原生http.Client+prompb.WriteRequest序列化手动发 POST - 或者改用官方推荐的
prometheus/client_golangv1.17+ 的prometheus.NewRemoteWriteExporter,但必须传入Headersmap:{"X-Scope-OrgID": "prod-team-a"} - 别用 localhost 域名:Docker 网络里,Go 服务容器访问
mimir-distributor服务名,别写宿主机 IP,否则 ring 发现失败
limits.yaml 中必须为租户设 ingestion_rate 和 max_global_series_per_user
没配 limits,Mimir 默认限流极严(ingestion_rate: 100),Go 服务一开 debug 日志或打点密集,立刻被 429 Too Many Requests 拒绝,且无明确错误提示。
- 关键配置项必须写进 Mimir 的
limits.yaml,而非单个租户配置文件:每个租户都要显式声明,否则走全局默认值 -
ingestion_rate单位是 series/sec,不是 bytes/sec —— Go 服务每秒打点 500 次 Counter,可能生成上千 series(尤其带 label 组合时),建议初设为5000 -
max_global_series_per_user必须大于你预估的总 series 数,否则 Ingester 拒收新 series;查sum by (tenant) (count_over_time({__name__=~".+"}[1h]))可估算 - 租户名不能含下划线或大写字母:
X-Scope-OrgID: prod-team-a✅,PROD_TEAM_A❌(ring 解析失败)
对象存储 backend 必须禁用 filesystem,且所有组件共用同一份 s3 config
开发时用 filesystem 后端能跑通,但一上生产,Ingester 写进去的数据 Querier 就读不到——因为 filesystem 是本地路径,多实例间不共享。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
-
blocks_storage.backend必须设为s3或gcs,绝对禁止filesystem;哪怕单节点测试也建议用 MinIO - MinIO endpoint、bucket、access key 必须在
mimir.yaml里统一配在blocks_storage.s3下,且 Distributor/Ingester/Querier/Compactor 全部加载同一份 config - Ingester 的
ingester.ring.store必须设为memberlist(非consul),否则 ring 状态不同步,Querier 找不到活跃 Ingester - S3 region 必须显式指定,哪怕 MinIO 也填
us-east-1;漏填会导致签名失败,日志里只报failed to put block,不提 region
Querier 查询时要绕过 Ingester 缓存窗口,避免冷数据查不到
刚写入的指标能查到,但 6 小时前的归档数据返回空?大概率是 Querier 默认只查最近 6 小时 Ingester 内存里的数据,老数据全在对象存储里,但没触发 Compactor 合并或没走 store-gateway 路径。
- 启动 Querier 时加参数:
--querier.query-ingesters-within=1h(不是 0),否则完全跳过 Ingester,冷数据又没配 store-gateway 就查不到 - 必须部署
store-gateway组件,并确保它和 Querier 共享同一blocks_storage配置;它负责从 S3 加载索引和 chunk,Querier 通过--store-gateway-address发现它 - Compactor 必须运行且健康:
/ready返回 200,且日志有compacting blocks;否则旧 block 不合并,store-gateway 加载慢甚至超时 - 查冷数据时 PromQL 加
@时间修饰符没用——Mimir 不支持;得靠time() - 7*24*3600这种硬算,或 Grafana 时间范围选“Last 7 days”
最易被忽略的是租户 header 和 limits 的耦合:header 写错,数据进不去;limits 没配,数据进得去但几分钟后被限流截断;两者都对了,对象存储配置错一点,查的时候就变成“数据存在但查不到”。这三环缺一不可,调一项就得全链路验证一次。

















