可观测性时序数据库后端指标监控【免费下载链接】cortexA horizontally scalable, highly available, multi-tenant, long term Prometheus.项目地址https://gitcode.com/gh_mirrors/cortex6/cortex点击查看免费下载导读Cortex 作为多租户的长期 Prometheus 存储系统其租户模型默认将数据隔离在不同租户内这虽然保证了安全性与配额管理却也阻止了单个 PromQL 查询同时覆盖多个租户的数据。本文以 Cortex 官方技术提案 docs/proposals/cross-tenant-query-federation.md 为核心骨架系统讲解跨租户查询联邦的设计动机、三大核心挑战及其解决方案并结合当前仓库中pkg/querier/tenantfederation的完整实现源码与配置参考带你掌握如何通过X-Scope-OrgID: tenant-a|tenant-b的方式发起跨租户查询、__tenant_id__标签的注入与保留语义、以及限额/公平性/可观测性在多租户查询下的处理方式。读完本文你将能够配置并安全地启用这一实验性功能。为什么需要跨租户查询联邦背景与动机在大型组织中Cortex 常被采用每个部门一个租户的租户模型例如team-a、team-b、team-c分别代表不同团队。这种模型带来的直接问题是当一个团队需要同时查看多个部门的数据例如对比各团队的服务质量指标时由于租户隔离单个 PromQL 查询无法跨越租户边界。提案的初衷正是克服这一限制允许查询覆盖来自多个 Cortex 租户的数据同时不破坏租户隔离本身的安全性。备选方案的评估与取舍提案在确定最终设计前系统评估了两种备选方案并给出了放弃理由理解这些取舍有助于你判断跨租户联邦的适用边界。方案一在 PromQL API 客户端聚合理论上PromQL API 客户端如 Grafana可以通过多个数据源 Transformations 对来自多个租户的查询结果做聚合关联。但该方案有两个致命缺点每个 PromQL API 客户端都需要单独支持多源聚合能力改造面大已用 PromQL 写好的查询无法不经额外工作就跨租户复用。因此该方案未被采纳。方案二在查询前端做多租户聚合另一种思路是在 query-frontend 内完成部分查询结果的聚合把查询按租户拆成子查询再把部分结果归约为最终结果。提案指出astmapper包虽采用了类似思路但无法并行化所有查询类型理想的跨租户联邦应支持完整的 PromQL 语言而不同查询函数与操作符所需的聚合算法各不相同实现复杂度极高。因此该方案同样被放弃转而选择在更底层的 querier 层进行合并。跨租户查询联邦的三大挑战与设计挑战一无重叠地聚合数据问题不同租户中的序列可能拥有完全相同的标签集直接合并会产生标签冲突无法区分数据来源。设计为了始终能正确识别租户多租户查询应在结果中注入名为__tenant_id__的标签其值为租户 ID若结果中已存在同名标签则原值被保留到前缀为original_的新标签中即original___tenant_id__。同时针对租户标签的选择器label selector应与其他任何标签一样工作——通过匹配__tenant_id__即可过滤参与查询的租户。源码印证该设计在 pkg/querier/tenantfederation/merge_queryable.go 中体现为两个常量const ( defaultTenantLabel __tenant_id__ retainExistingPrefix original_ defaultMaxConcurrency 16 )标签的覆盖并保留逻辑由setLabelsRetainExisting实现merge_queryable.go若原系列已存在__tenant_id__标签先把旧值写入original___tenant_id__再写入新租户 ID。注释明确说明该保留行为不递归——如果结果已同时含有__tenant_id__和original___tenant_id__后者的旧值会丢失这也被列入提案的 Future work。Select方法merge_queryable.go展示了标签注入与租户过滤的完整流程通过filterValuesByMatchers解析匹配__tenant_id__的 matcher得出需要查询的租户子集将不含租户标签的 matcher 转发给各租户的底层 querier每个租户的结果经addLabelsSeriesSet包装注入__tenant_id__标签最后通过storage.NewMergeSeriesSet合并为单一序列集。对应测试 pkg/querier/tenantfederation/merge_queryable_test.go 中明确验证了three tenants and the__tenant_id__label set、original___tenant_id__保留等行为。挑战二如何向用户暴露该功能问题租户 ID 目前从X-Scope-OrgIDHTTP 头读取且租户 ID 有文档化的命名限制仅允许字母、数字及! - _ . * ( )等字符见 pkg/util/users/tenant.go 中的isSupported校验。设计在查询路径上用户应能在单个X-Scope-OrgID头中指定多个租户 ID用|分隔多个租户 ID 沿系统链路一直传播到 querier。querier 组件返回的Queryable实例被mergeQueryable包装它按租户分别创建Queryable并聚合其结果使下游组件将其视作单个租户查询。源码印证核心实现位于 pkg/querier/tenantfederation/tenant_federation.goNewQueryableL42-L51把上游 Queryable 包装为NewMergeQueryabletenantQuerierCallbackL53-L74通过users.TenantIDs(ctx)从上下文取出全部租户 ID为每个租户创建对应的 queriermergeQuerier在Select/LabelValues/LabelNames方法中并行调度各租户的查询并发度由maxConcurrent控制并支持byPassWithSingleQuerier当请求只涉及单个租户时直接透传不注入__tenant_id__标签从而实现平滑开启。多个租户 ID 的解析由租户解析器完成pkg/util/users/resolver.goMultiResolver.TenantIDsL118-L128把X-Scope-OrgID按|拆分逐个校验后经NormalizeTenantIDs排序去重pkg/util/users/tenant.go而SingleResolver则严格要求单个租户——不期望多租户 ID 的组件如数据写入链路会通过TenantID返回user.ErrTooManyOrgIDs错误这正是提案所说不支持多租户 ID 的组件必须报错的实现。在模块装配层面pkg/cortex/modules.go 的initTenantFederation在TenantFederation.Enabled时依次包装三种查询入口t.QuerierQueryable querier.NewSampleAndChunkQueryable(tenantfederation.NewQueryable(t.QuerierQueryable, t.Cfg.TenantFederation, byPassForSingleQuerier, reg)) t.MetadataQuerier tenantfederation.NewMetadataQuerier(t.MetadataQuerier, t.Cfg.TenantFederation, reg) t.ExemplarQueryable tenantfederation.NewExemplarQueryable(t.ExemplarQueryable, t.Cfg.TenantFederation, byPassForSingleQuerier, reg)即时序数据、metric 元数据metadata_merge_querier.go与 exemplar 数据exemplar_merge_queryable.go三个维度均支持联邦聚合。挑战三跨租户查询的限额、公平性与可观测性问题在 Cortex 中租户 ID 是以下机制的主键决定某个查询适用的限额limitsquery-frontend 按租户维护查询队列以实现公平调度查询相关指标以user标签暴露。多租户查询下这些机制不再正确。设计涉及多个租户的查询其标识符由有序、去重后的租户 ID 列表经|连接派生而来。由于先排序后连接同一组租户无论以何种顺序提交都会得到可复现的标识符。该特性处于实验阶段因此伴随以下已知缺陷租户 ID 组合数量可能带来基数cardinality成本应用于多租户查询中单个租户的查询限额会被忽略。源码印证前端处理链路上pkg/frontend/transport/handler.go 先解析全部租户 ID再用users.JoinTenantIDs(tenantIDs)内部即strings.Join(tenantIDs, |)见 pkg/util/users/tenant.go生成统一标识符用于队列、限流与指标标签同一处代码实现了-tenant-federation.max-tenant的强制校验当启用联邦且租户数超过上限时直接返回tenantfederation.ErrTooManyTenantstoo many tenants, max: %d, actual: %d并计数cortex_rejected_queries_total联邦查询自身提供专用可观测性指标定义于 merge_queryable.gocortex_querier_federated_tenants_per_query另有cortex_querier_federated_tenants_per_metadata_query、cortex_querier_federated_tenants_per_exemplar_query见 metadata/exemplar 实现桶边界为{1, 2, 4, 8, 16, 32, 64}可直观观察单次查询涉及的租户数量分布。配置指南完整参数说明tenant_federation配置块在 docs/configuration/config-file-reference.md 中有完整参考对应源码结构体见 pkg/querier/tenantfederation/tenant_federation.go。全部参数均可通过 YAML 或 CLI flag 配置tenant_federation: # 是否启用多租户查询联邦。必须对所有 Cortex 服务querier、query-frontend、ruler 等同时开启。 # CLI flag: -tenant-federation.enabled [enabled: boolean | default false] # 处理单个联邦查询的工作协程数。 # CLI flag: -tenant-federation.max-concurrent [max_concurrent: int | default 16] # 单次查询最多涉及的租户数上限0 表示不限制。 # CLI flag: -tenant-federation.max-tenant [max_tenant: int | default 0] # [实验性] 开启后 X-Scope-OrgID 的值可接受正则表达式自动匹配到的租户 ID 全部参与查询。 # 匹配规则遵循 Prometheus 正则语法用户发现基于扫描块存储新租户通常需上传一个块约 2 小时后才能被查询到。 # CLI flag: -tenant-federation.regex-matcher-enabled [regex_matcher_enabled: boolean | default false] # [实验性] 配合 regex matcher扫描租户的频率扫描策略取决于 -blocks-storage.users-scanner.strategy。 # CLI flag: -tenant-federation.user-sync-interval [user_sync_interval: duration | default 5m] # [实验性] 正则匹配结果缓存大小缓存项含正则模式与解析出的租户 ID 列表设为 0 或负数禁用缓存。 # CLI flag: -tenant-federation.regex-cache-size [regex_cache_size: int | default 1000] # [实验性] 开启后单个租户的查询错误被降级为 warning仍返回其余租户的部分结果。 # CLI flag: -tenant-federation.allow-partial-data [allow_partial_data: boolean | default false]最小启用配置只需一行 flag-tenant-federation.enabledtrue按文档 docs/guides/ruler-tenant-federation.md 的说明-tenant-federation.enabled必须在所有 Cortex 服务上设置。使用方式启用后查询时将多个租户 ID 以|分隔放入X-Scope-OrgID头curl -H X-Scope-OrgID: team-a|team-b|team-c \ http://cortex-query-frontend/api/v1/query?queryup返回的每个序列都会携带__tenant_id__标签标明来源租户若某租户的数据原本就有__tenant_id__标签其原值会被移到original___tenant_id__。你也可以在 PromQL 中直接按该标签过滤例如up{__tenant_id__team-a}此时只查询匹配的租户未匹配租户的底层查询不会被执行见filterValuesByMatchers逻辑merge_queryable.go。正则匹配模式实验性开启-tenant-federation.regex-matcher-enabled后X-Scope-OrgID可传正则表达式例如X-Scope-OrgID: user-.所有匹配的租户自动参与查询。该能力由 pkg/querier/tenantfederation/regex_resolver.go 中的RegexResolver实现通过users.NewScanner周期性扫描块存储发现全部租户服务启动时先同步一次之后按user_sync_interval周期同步见 L117-L141使用 Prometheus 的labels.NewFastRegexMatcher对已知租户 ID 做正则匹配L202-L216匹配结果缓存在 LRU 缓存默认容量 1000regex_cache_size控制租户集合变化时自动清空缓存L156-L162命中max_tenant上限时返回 400 错误L246-L249配套指标cortex_regex_resolver_discovered_users、cortex_regex_resolver_matched_cache_size、cortex_regex_resolver_matched_cache_hits_total/_misses_total、cortex_regex_resolver_last_update_run_timestamp_seconds。需要留意的是由于用户发现依赖扫描块存储新租户通常要等上传块约 2 小时后才可被正则匹配到而按 docs/guides/ruler-tenant-federation.md 的提示开启正则匹配后含正则元字符.、*、(、)的租户 ID 在source_tenants中会被拒绝。部分数据返回Partial Data默认情况下联邦查询中任意一个租户查询失败会导致整体查询失败错误信息会标注具体租户例如error querying tenant id team-b。开启-tenant-federation.allow-partial-datatrue后行为变为单个租户的查询错误被降级为 warning 并附加(partial data returned)标记继续返回其他租户的结果该逻辑贯穿时序数据merge_queryable.go 的Err/Warnings处理、元数据metadata_merge_querier.go与 exemplar 查询exemplar_merge_queryable.go。在关键指标可用性优先于完整性的场景例如多团队聚合告警中该选项能显著提升查询可用性。Ruler 中的跨租户联邦提案将Ruler 支持多租户查询列为未来工作但当前仓库已将其落地相关指南见 docs/guides/ruler-tenant-federation.md。实现要点规则组可通过source_tenants声明多个源租户例如team-a|team-b|team-c每条规则求值时X-Scope-OrgID被设为team-a|team-b|team-c查询行为与普通联邦查询完全一致每个序列同样携带__tenant_id__标签单源租户时不注入该标签当 ruler 通过-ruler.frontend-address走 query-frontend 求值时由前端与 querier 完成联邦否则由 ruler 自行合并源租户结果权限控制由 pkg/ruler/federation.go 的federatedRulesChecker实现通过-ruler.enable-federated-rules开关、允许/禁止租户名单、max_tenant上限与正则元字符校验来约束哪些租户可以创建联邦规则组及其合法源租户集合。提案结论与后续工作提案给出的三大挑战均已落地实现对应上游 PR #3250挑战状态无重叠地聚合数据__tenant_id__标签注入与保留已实现向用户暴露功能X-Scope-OrgID多租户 mergeQueryable聚合已实现跨租户查询的限额、公平性与可观测性排序去重后\|连接的标识符已实现提案明确列出的后续工作方向包括Ruler 的跨租户支持——在规则中直接使用多租户查询当前仓库已实现见上文可插拔的标识符来源——使限额/公平性/可观测性可基于其他维度例如用户而非租户派生标识符自定义租户标签名——目前__tenant_id__名称固定未来可通过配置项修改递归保留重叠的租户标签值——目前若结果已含__tenant_id__与original___tenant_id__后者的旧值会在再次覆盖时丢失。实践建议与注意事项基于提案与源码启用跨租户查询联邦时建议关注以下几点全链路开启-tenant-federation.enabled需要在 querier、query-frontend 等所有相关服务上统一开启否则多租户 ID 可能在链路上被SingleResolver拒绝写入路径不受影响数据摄入ingest链路仍严格要求单租户多租户 ID 会被拒绝租户隔离的写入语义不受破坏限额语义变化联邦查询的限额作用于租户 ID 组合而非单个租户单个租户的查询限额会被忽略建议用-tenant-federation.max-tenant限制单次查询涉及的租户数控制基数成本与资源占用正则模式需谨慎regex_matcher_enabled依赖块存储扫描发现租户新租户最长约 2 小时延迟且租户 ID 字符集会受到正则语法的额外约束可观测性利用cortex_querier_federated_tenants_per_query等指标监控联邦查询的租户规模结合cortex_regex_resolver_*指标排查正则匹配与缓存状况平滑过渡byPassWithSingleQuerier保证单租户查询不经合并路径、不注入__tenant_id__标签因此开启联邦不会改变现有单租户查询的结果形态可放心灰度。如需深入了解建议继续阅读源码pkg/querier/tenantfederation/tenant_federation.go、pkg/querier/tenantfederation/merge_queryable.go、pkg/util/users/resolver.go 及其测试文件 pkg/querier/tenantfederation/merge_queryable_test.go以及配置参考 docs/configuration/config-file-reference.md 中的tenant_federation小节。赞分享可观测性时序数据库后端指标监控【免费下载链接】cortexA horizontally scalable, highly available, multi-tenant, long term Prometheus.项目地址https://gitcode.com/gh_mirrors/cortex6/cortex点击查看免费下载相关推荐Cortex租户联邦查询实现跨租户数据聚合的完整指南Cortex租户联邦查询实现跨租户数据聚合的完整指南 Cortex租户联邦查询是Cortex多租户架构中的关键特性它允许用户在一个查询中聚合和分析来自多个租可观测性时序数据库后端指标监控Thanos 查询链路多租户Query Path Tenancy设计与落地从提案到源码实现Thanos 查询链路多租户Query Path Tenancy设计与落地从提案到源码实现 本文以 Thanos 仓库中已接受的提案文档 docs/pro可观测性云原生时序数据库运维Apache Doris跨数据库查询联邦查询实现方案Apache Doris跨数据库查询联邦查询实现方案 在企业数据分析场景中数据往往分散在不同的数据库和存储系统中如MySQL、Hive、ElasticseOLAP数据库大数据实时分析上一篇Flutter设计模式跨平台适配iOS与Android界面一致性终极指南下一篇8GB显存也能跑Control-LoRA轻量化图像控制全攻略从边缘检测到深度估计的4大实战案例创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考