资讯详情

Grafana Mimir Compartments 架构中的全局 Ruler:远程规则评估与跨写入分区的结果写入

📅 2026/10/13 2:18:35 | 华诺云谱 👁 阅读
Grafana Mimir Compartments 架构中的全局 Ruler:远程规则评估与跨写入分区的结果写入
时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载导读本文基于 Grafana Mimir 仓库中的 Ruler 设计文档位于 compartments 架构文档集深入讲解在 compartments分区舱室架构下 Ruler 如何作为全局查询层的一部分工作规则评估通过远程评估路径走专属的 ruler query-frontend / query-scheduler / ruler querier规则结果则通过所在可用区的 headless distributor 服务借助 gRPC 客户端负载均衡写入到对应写入分区的 Kafka 集群再按租户 指标名分片到读取分区。读完本文你将掌握 compartments 模式下 Ruler 的完整调用链、双层分片原理、关键配置参数以及该设计背后的权衡。背景说明compartments 是 Mimir 中处于实验阶段、默认关闭的架构见 状态与限制它将单个 Mimir cell 按系列切分为多个互相独立的子 cellcompartment。其中写路径由写分区write compartmentwc-id承担存储侧由读分区read compartmentrc-id承担二者数量相互独立、没有一一对应关系。一、Ruler 在 compartments 架构中的定位按照 compartments 总览文档一个 Mimir cell 被拆成两套互相独立的分区集合写分区Write compartments负责摄入侧由 distributors 加一套专属 Kafka 集群组成读分区Read compartments负责指标存储侧包含 ingesters、store-gateways、block-builders、compactors全局查询层Global query layerquery-frontend、query-scheduler、querier、ruler 横跨所有分区不属于任何一组。Ruler 属于全局查询层这一点与原文档的表述完全一致它不再以某个读写分区的组成部分运行而是以 cell 级的多可用区multi-zone舰队形式存在。具体而言Ruler 实例使用一个全局 ring来对规则组rule groups做分片规则组从共享的 ruler storage独立于各读分区的对象存储桶读取每个可用区都有一份 ruler、ruler 查询路径以及 distributor 切片zonal slice而每个写分区则拥有一个 cell 级的逻辑 Kafka 集群。从源码看pkg/ruler/ruler.go 中定义了RulerRingKey ring即 ruler ring 在 KVStore 中的注册键规则组的拉取与分片正是围绕这个全局 ring 展开的。二、规则评估远程评估与读分区定位查询2.1 远程规则评估Remote rule evaluation在 compartments 模式下Ruler不使用内部查询路径直接读数据而是把每一次规则评估发送给所在可用区的 ruler query-frontendRuler 将每条规则的 PromQL 表达式封装为远程读请求发给本可用区的ruler query-frontend查询经过ruler query-scheduler排队调度由ruler querier实际去查询读分区其查询行为与普通查询完全一致按照指标名定位到特定读分区必要时向多个读分区 fan-out然后合并结果。在本地开发环境的配置 development/mimir-compartments/config/mimir.yaml 中可以看到对应设置ruler: alertmanager_url: http://alertmanager-1:8041/alertmanager,http://alertmanager-2:8042/alertmanager,http://alertmanager-3:8043/alertmanager for_grace_period: 1s # Evaluate rules via query-frontend (remote rule evaluation). query_frontend: address: dns:///query-frontend:9095这里ruler.query_frontend.address使用dns:///前缀的 gRPC 地址以启用客户端负载均衡。对应的源码实现位于 pkg/ruler/remotequerier.goQueryFrontendConfig支持dns:///形式的 gRPC 地址或 HTTP(S) 地址对接 Prometheus 兼容服务并提供-ruler.query-frontend.query-result-response-formatjson或protobuf默认protobuf与-ruler.query-frontend.max-retries-rate等参数。实际的远程读请求通过 Prometheus Remote Read 协议发送到/api/v1/read端点见 pkg/ruler/remotequerier.go。2.2 查询如何定位读分区规则的表达式在读取数据时遵循与普通查询相同的 compartment-aware 定位逻辑详见 读分区文档等值匹配单个指标名该指标的所有序列只存在于一个读分区查询仅发给那个分区指标名被限制为有限集合例如等价于a|b|c的正则查询发给这些指标名所属分区的并集其余情况如开放正则.或没有指标名过滤查询 fan-out 到所有读分区并合并结果。这一逻辑在源码 pkg/compartments/router.go 的CompartmentsForMatchers中实现遍历__name__matcher优先取等值匹配唯一确定一个分区其次取可枚举的正则匹配集取最小集合映射到分区并集无法收缩时返回全部分区。同时要强调持有输入序列的读分区并不决定结果写到哪里。规则产生的序列会按它们自己的指标名重新路由因此一条规则完全可以从一组读分区读数据把结果写到另一组读分区——这是本文第三、四节的核心。三、写入规则结果zonal headless distributor 服务3.1 调用链与客户端负载均衡规则评估完成后无论是 recording rule 还是 alerting ruleRuler 都会把生成的序列通过 gRPC 推送给所在可用区的一个 headless distributor 服务。该服务暴露了本可用区内每个写分区的 distributor 切片gRPC 客户端负载均衡为每个请求选择其中一个端点。这里的headless体现在部署上在 Kubernetes 中对应 distributor 的 headless servicegRPC 端口在本地开发环境中development/mimir-compartments/docker-compose.jsonnet 为distributor-wc-0、distributor-wc-1共享了同一个网络别名distributornginx 通过该别名在两者之间做负载均衡。Ruler 的对应参数同样使用 DNS 形式-ruler.distributor.addressdns:///distributor:9095该参数的源码定义在 pkg/ruler/distributor_client.goruler.distributor.address规则结果要推送的 distributor gRPC 地址为空时 Ruler 使用内部 distributor非 compartments 模式填写dns:///前缀的 DNS 地址时启用 gRPC 客户端负载均衡ruler.distributor.remote-timeout默认10s单次推送请求的超时ruler.distributor.grpc-client-configgRPC 客户端详细配置。校验逻辑pkg/ruler/distributor_client.go要求地址必须是 gRPC 地址拒绝http:///https://且使用服务发现时必须满足dns:///三斜杠格式。3.2 被选中的 distributor 完成双层分片被选中的 distributor 会把请求送入自己写分区的 Kafka 集群并对每条生成的序列做与普通写入完全相同的双层分片见 分片文档按租户 指标名分片到读分区read_compartment hash(user_id, metric_name) % num_read_compartments因为 user ID 参与了哈希同一指标名在不同租户下可能落到不同读分区在读分区内按序列标签哈希分片到分区partition复用 Mimir 原有的系列标签哈希分片逻辑。对应的哈希实现见 pkg/mimirpb/series_sharding.go 的ShardByMetricName(userID, metricName)它先哈希 user ID 再加入 metric name写路径侧的分组逻辑见 pkg/distributor/compartments.go 的getCompartmentTokensForWriteRequest它遍历请求中的每条序列与 metadata调用router.CompartmentForMetric归组到对应读分区并为每个条目计算分区 ring token然后过滤掉空分区。TopicRouterpkg/compartments/router.go则把read-compartment-id占位符替换成实际读分区 ID得到每个分区的 Kafka topic例如mimir-ingest-rc-read-compartment-id占位符常量定义在 pkg/compartments/config.go。Ruler 侧的推送客户端实现同样在 pkg/ruler/distributor_client.goPush通过distributorpb.DistributorClient.Push发送mimirpb.WriteRequest并在请求元数据中标记client-id: ruler以便 distributor 中间件识别规则输出大请求会按最大可发送大小拆分splitWriteRequest推送失败时对Unavailable、DeadlineExceeded、Internal等可重试错误按退避策略重试pushWithRetries/isRetryableDistributorPushError并暴露cortex_ruler_remote_distributor_requests_per_write_request指标记录单个写入请求被拆分的次数。四、完整架构图原文档提供了如下 Mermaid 架构图展示了一个代表性可用区内 Ruler 的读写路径以 2 个读分区、2 个写分区为例读图时需要抓住几个关键点读写两条路径并行且独立左侧是评估查询路径Ruler → ruler query-frontend → ruler query-scheduler → ruler querier → 读分区右侧是结果写入路径Ruler → zonal headless distributor service → 各写分区 distributor → Kafka → 读分区。Kafka 集群按写分区隔离每个写分区拥有一个 cell 级的逻辑 Kafka 集群图中wc-0、wc-1各一个而ingest-rc-idtopic 在每个写分区的 Kafka 集群里都存在一份因为每个写分区都会写入每个读分区见 写分区文档。2×2 只是示意两类分区都跨可用区分布数量相互独立不存在一一配对图中展示在可用区内的 ruler、ruler 查询路径和 distributor 切片在每个可用区都会重复出现。五、compartments 模式下 Ruler 的特殊行为5.1 不再运行内部 distributor在 compartments 部署中Ruler不会为规则结果写入运行内部 distributor非 compartments 模式下 Ruler 可以直接把结果交给进程内的 distributor。这正是 pkg/ruler/distributor_client.go 中ruler.distributor.address默认值为空时的分支说明If empty, the ruler writes using the internal distributor——配置了远程地址后写入就完全改走 gRPC 远程路径。5.2 评估与写入是分离的两步原文档明确说明PromQL 表达式评估与结果摄入是两个独立步骤。可能出现评估成功但结果写入失败的情况此时规则被报告为unhealthy一次evaluation failure被记录。这意味着 compartments 并不会让规则写入搭便车成功——结果写入的失败不会被评估成功掩盖。5.3 Alertmanager 通知路径不受影响规则产生的告警通知继续走既有的 Alertmanager 通知路径不会经由 compartments 路由。本地开发环境的配置也印证了这一点ruler.alertmanager_url直接指向一组 alertmanager 实例见 development/mimir-compartments/config/mimir.yaml与分区无关。六、为什么 Ruler 保持全局设计与权衡6.1 为什么不能把 Ruler 放进某个写分区原文档给出了两个候选方案的否定理由把 Ruler 放进单个写分区会导致所有规则结果请求都指向该分区形成单一热点与故障集中点把 Ruler 按读分区分散、并逐一绑定到写分区因为读写分区的数量相互独立这种映射无法干净地对齐。因此 Ruler 留在全局层把每一次结果写入请求都发给分区内zonal的 distributor 服务客户端负载均衡从一个包含所有写分区 zonal 切片的端点池中挑选一个 distributor被选中的 distributor 再执行常规的读分区分片 分区内分片。6.2 明确的权衡原文档坦诚地指出了代价compartments 不能隔离 Ruler 的调度与评估。如果整个 Ruler 舰队出现问题会影响所有规则的评估——哪怕其中一些规则本可以被定位到不同读分区。不过当一个规则表达式可以被收缩到读分区的一个子集时读分区仍然能限制数据路径data-path上的故障影响面即查询爆炸半径仍然得到缩减。6.3 与全局 ring 的对应关系Ruler 使用单个全局 ring 进行规则组分片这与写分区侧distributors 共享单一全局 ring的设计思路一致后者仅用于统计全局 distributor 数量以驱动全局租户限流见 写分区文档。全局 ring 的存在是Ruler 作为全局层而非分区内组件这一设计的直接体现。七、配置实践在本地 compartments 环境中验证仓库提供了本地开发环境development/mimir-compartments2 个写分区 2 个读分区可以端到端验证本文描述的行为详见 状态与限制文档。关键配置片段汇总来自 development/mimir-compartments/config/mimir.yaml 与 development/mimir-compartments/docker-compose.jsonnet# 启用 compartments 并声明读写分区数量 compartments: enabled: true read: num_compartments: 2 write: num_compartments: 2 # 全局启用 ingest-storage 写入侧各组件通过 CLI 覆盖为自己的分区服务 ingest_storage: enabled: true kafka: address: kafka-wc-0:9092 topic: mimir-ingest-rc-0 ruler: # 远程规则评估发往本可用区的 query-frontend query_frontend: address: dns:///query-frontend:9095 # 告警通知继续走既有 Alertmanager 路径 alertmanager_url: http://alertmanager-1:8041/alertmanager,... ruler_storage: s3: bucket_name: mimir-ruler各写分区的 distributor 通过 CLI 指定自己的 Kafka 集群与 topic 模板-distributor.write-compartment-idwc-id -ingest-storage.kafka.addresskafka-wc-write-compartment-id:9092 -ingest-storage.kafka.topicmimir-ingest-rc-read-compartment-id而 Ruler 实例则通过以下参数把结果写入交给分区内 distributor 服务、把评估查询交给分区内 query-frontend见 development/mimir-compartments/docker-compose.jsonnet-ruler.distributor.addressdns:///distributor:9095环境中两个读分区的指标都可查询当查询等值匹配某个指标名时由持有该指标名的读分区单独服务没有指标名等值匹配时则 fan-out 到两个读分区。八、当前实现状态与局限根据 状态与限制文档全局 Ruler 评估与写入已被列为当前已实现的部分Ruler 通过远程的 compartment-aware 查询路径评估规则并把生成的序列发给横跨所有写分区的 zonal distributor 端点池被选中的 distributor 再执行常规读分区分片。但 compartments 整体仍是实验性且默认关闭的特性部分能力尚未补齐例如 per-compartment block-builders 尚未进入 jsonnet 部署库、shuffle sharding 与集成测试等写路径能力仍在建设中。因此本文描述的全局 Ruler 行为适用于开启 compartments 的部署场景生产落地前应结合 状态与限制文档 与 配置文档 确认当前支持的边界。延伸阅读compartments 总览与架构双层分片与分段标签选择读分区存储与定位查询写分区Kafka 隔离与全局 ring命名规范wc- / rc- compartments 配置归属说明本地开发环境配置本地开发环境编排定义赞分享时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载相关推荐OpenScreen麦克风设置增益调整与降噪技巧终极指南OpenScreen麦克风设置增益调整与降噪技巧终极指南 OpenScreen是一款强大的开源屏幕录制工具能够创建高质量演示视频完全免费且无水印。本文将详桌面应用音视频视频处理屏幕录制Loki Ruler 远程规则评估Remote Rule Evaluation设计解析与实现指南Loki Ruler 远程规则评估Remote Rule Evaluation设计解析与实现指南 导读 本文基于 Loki 社区 LIDLoki Impr可观测性日志分析后端微服务对象存储云原生Cortex Ruler 租户联邦Federated Rules跨租户规则评估的设计与实战Cortex Ruler 租户联邦Federated Rules跨租户规则评估的设计与实战 导读 本文围绕 Cortex 开源仓库中的 Ruler 租户联可观测性时序数据库后端指标监控上一篇MNN Diffusion 文生图/文生视频推理引擎使用指南Stable Diffusion、Sana、SD3.5 与 Wan2.1 全流程实战下一篇SenseVoice多模态语音理解架构深度解析与工程实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑