• 【博客487】prometheus-----高基数问题的危害以及如何排查和避免


    prometheus-----高基数问题的危害以及如何排查和避免

    什么是基数(Cardinality)?

    基数 是指一个标签的总体数值的计数

    比如:server_responses有两个指标status_code和environment,标签status_code的基数是5,
    (即:1xx,2xx,3xx,4xx,5xx), environment的基数是2(即prod,dev),
    而指标server_responses的总体基数是10。
    
    • 1
    • 2
    • 3

    高基数的典型案例

    url,userid,经纬度,uuid,typeid,手机号…

    Time Series

    一个时间序列由一系列的 (timestamp, value)按照时间排序而成。
    时间戳的精度是毫秒,value是64位浮点数。
    每个时序都有名称,同时可以有任意数量的标签。
    如果两个时序的名称或者标签的键值对有任一不同,那么这两个时序也就不同。
    
    • 1
    • 2
    • 3
    • 4

    注意:请记住,每个唯一的键值标记对组合(labels)都表示一个新的时序型数据,其会大幅增加所存储的数据量。不要使用标记(labels)来存储高基数维度(很多不同的标记值),例如用户 ID、电子邮箱地址,或者其他不受限制的数值集合。

    高基数问题本质

    高基数问题其实是指存在高基数label,高基数label很多时,将会有非常多的Series

    警惕维度(Cardinality)过高的指标—即:高基数指标问题

    label 对于多维监控非常有用,一个指标的基数是指标中所有 label 枚举值组合的笛卡尔乘积. 因此:

    label 中不适合放 用户 ID/设备 ID/URL 参数 等高基数的值. 单个 label 值不超过 128 个字符;
    避免一个指标过多的 label 组合, 不必要的组合 label 可以拆解为多个指标, 以便降低指标基数, 提高该指标的查询性能

    建议:

    Metrics 更关注系统级别的高效指标而不是单个请求级别, 不要在 Metrics 中放过多的细节 label, 单独 Metrics 无法解决所有的可观测性问题, 详细的信息应记录 Logs 和 Traces 中, 或者在 Exemplar 带上 traceID, 充分利用三大信号 Metrics/Logs/Traces 关联 一起来观测系统

    高基数的负面影响

    1、监控查询很慢甚至失败

    2、计算存储资源开销巨大

    3、监控信息里充斥着大量噪音干扰

    查看高基数指标

    查看方法:

    Prometheus UI -> Status -> TSDB Status -> Head Cardinality Stats

    可以看到:

    1、value最多的 Label

    在这里插入图片描述

    2、最多的 series 的指标

    在这里插入图片描述

    3、内存使用量最多的 Label

    在这里插入图片描述

    4、根据 Label 键值对匹配, series 最多的键值对有

    在这里插入图片描述

    高基数危害

    怕的不是单个高基数标签,怕的是多个高基数标签组合,形成指数增长

    高基数问题来源

    1.某些 label 不合理, 值很多甚至无穷;

    2.某些 指标 不合理, 值很多;

    3.Prometheus 整体的全部 series 量太大

    优化高基数指标

    查看高基数指标:

    从prometheus界面的status中的tsdb status中看到top 10 label names with label count
    
    • 1

    优化方法:

    1、从源头避免引入,非必要的标签不引入

    2、通过 Relabel 减少 Prometheus 指标的使用:使用drop来过滤

    write_relabel_configs:
    
      - source_labels: [__name__]
    
        regex: "apiserver_request_duration_seconds_bucket"
    
        action: drop
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、做数据切片

    将高基数label的metrics,按照各个高基数label进行拆分到多个metrics中去

    4、通过 recording rules 聚合指标并和 relabel drop 结合使用

    比如对于 apiserver_request_duration_seconds_bucket
    , 我需要的是一些高纬度的指标 - 如 API Server 的可用率, 那么这些指标可以通过 recording rules 进行记录和存储, 示例如下:

    groups:
    
      - interval: 3m
    
        name: kube-apiserver-availability.rules
    
        rules:
    
          - expr: >-
    
              avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) *
    
              24 * 30
    
            record: code_verb:apiserver_request_total:increase30d
    
          - expr: >-
    
              sum by (cluster, code, verb)
    
              (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"2.."}[1h]))
    
            record: code_verb:apiserver_request_total:increase1h
    
          - expr: >-
    
              sum by (cluster, code, verb)
    
              (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"5.."}[1h]))
    
            record: code_verb:apiserver_request_total:increase1h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    之后可以再在 remote_wirte,等阶段删掉原始指标:

    write_relabel_configs:
    
      - source_labels: [__name__]
    
        regex: "apiserver_request_duration_seconds_bucket"
    
        action: drop
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    为什么对于高基数的数据,Prometheus不是一个好的选择

    CAUTION: Remember that every unique combination of key-value label pairs represents a new time series, which can dramatically increase the amount of data stored. Do not use labels to store dimensions with high cardinality (many different label values), such as user IDs, email addresses, or other unbounded sets of values.

    注意:请记住,键值标签对的每个唯一组合都代表一个新的时间序列,这可以显着增加
    存储的数据量。请勿使用标签存储具有高基数(许多不同的标签值)的尺寸,例如用户ID,
    电子邮件地址或其他无限制的值集。

    高基数优化最佳实践

    假设:有许多机器被采集,我们可以增加label内容如下:机房信息,机器ip,机器操作系统类型,机器大小

    机器ip就是大基数指标,引入会有问题吗:

    不会有问题,采集的metrics中,每个对象总要有一个特定信息来描述,所以这个标志性大基数指标是一定需要,不然识别不了对象。
    同样的道理,http指标中url这种大基数指标是不可避免的。
    这种大基数指标不会有影响,是因为整个label里面其实也就只有一个大基数指标,label的基数相乘,最终基数不会很大,是线性增长

    如果在基数识别的大基数指标中,再引入userid,uuid,typeid等其它高基数指标,就会使得label的基数相乘,最终基数很大,是指数性增长

    最佳实践:

    引入一个高基数的识别指标,然后根据这个高基数识别指标,再去查其它相关联信息。

    比如:根据机器ip再去查所属的用户,机器的uuid,型号id等

    比如:根据http信息中的url再去tracing系统中,根据tracing链去查找这次调用的过程和耗时等

  • 相关阅读:
    Codeforces 1684 E. MEX vs DIFF
    什么叫等响曲线?有什么用?
    C语言学习笔记(六):数组(1)
    php遍历某月份所有日期的实例
    视频转码教程:轻松制作GIF动态图,一键高效剪辑操作
    vscode里面进行git提交
    hash和history路由的区别
    【JAVASE系列】03_方法(定义,重载,递归)
    Android的权限管理系统工作原理详解
    【电气安全】安科瑞电气火灾监控系统在江苏某大学中设计与应用
  • 原文地址:https://blog.csdn.net/qq_43684922/article/details/126814335