前言

随着 Prometheus 监控的组件、数量、指标越来越多,Prometheus 对计算性能的要求会越来越高,存储占用也会越来越多。

在这种情况下,要优化 Prometheus 性能, 优化存储占用. 第一时间想到的可能是各种 Prometheus 的兼容存储方案, 如 Thanos 或 VM、Mimir 等。但是实际上虽然集中存储、长期存储、存储降采样及存储压缩可以一定程度解决相关问题,但是治标不治本。

  • 真正的本,还是在于指标量(series)过于庞大。
  • 治本之法,应该是减少指标量。有 2 种办法:

本次重点介绍第二种办法:如何根据实际的使用情况精简 Prometheus 的指标和存储占用?

思路

  1. 分析当前 Prometheus 中存储的所有的 metric name(指标项);
  2. 分析展示环节用到的所有 metric name,即 Grafana 的 Dashboards 用到的所有指标;
  3. 分析告警环节用到的所有 metric name,即 Prometheus Rule 配置中用到的所有指标;
  4. (可选)分析诊断环境用到的所有 metric name,即经常在 Prometheus UI 上 query 的指标;
  5. 通过 relabelmetric_relabel_configswrite_relabel_configskeep 2-4 中的指标, 以此大幅减少 Prometheus 需要存储的指标量.

要具体实现这个思路, 可以通过 Grafana Labs 出品的 mimirtool 来搞定.

我这里有个前后的对比效果, 可供参考这样做效果有多惊人:

  1. 精简前: 270336 活动 series
  2. 精简后: 61055 活动 series
  3. 精简效果: 将近 5 倍的精简率!

Grafana Mimirtool

Grafana Mimir 是一款以对象存储为存储方式的 Prometheus 长期存储解决方案, 从 Cortex 演化而来. 官方号称支持亿级别的 series 写入存储和查询.

Grafana Mimirtool 是 Mimir 发布的一个实用工具, 可单独使用.

Grafana Mimirtool 支持从以下方面提取指标:

  • Grafana 实例中的Grafana Dashboards(通过 Grafana API)
  • Mimir 实例中的 Prometheus alerting 和 recording rules
  • Grafana Dashboards JSON文件
  • Prometheus记alerting 和 recording rules 的 YAML文件

然后,Grafana Mimirtool可以将这些提取的指标与Prometheus或Cloud Prometheus实例中的活动 series 进行比较,并输出一个 used 指标和 unused 指标的列表。

Prometheus 精简指标实战

假设

假定:

  • 通过kube-prometheus-stack 安装 Prometheus
  • 已安装 Grafana 且作为展示端
  • 已配置相应的 告警规则
  • 除此之外, 无其他需要额外保留的指标

前提

  1. Grafana Mimirtool 从 releases 中找到 mimirtool 对应平台的版本下载即可使用;
  2. 创建 Grafana API token
  3. Prometheus已安装和配置.

第一步: 分析 Grafana Dashboards 用到的指标

通过 Grafana API

具体如下:

# 通过 Grafana API分析 Grafana 用到的指标
# 前提是现在 Grafana上创建 API Keys
mimirtool analyze grafana --address http://172.16.0.20:32651 --key=eyJrIjoiYjBWMGVoTHZTY3BnM3V5UzNVem9iWDBDSG5sdFRxRVoiLCJuIjoibWltaXJ0b29sIiwiaWQiOjF9

说明:

  • http://172.16.0.20:32651 是 Grafana 地址
  • --key=eyJr 是 Grafana API Token. 通过如下界面获得:

获取到的是一个 metrics-in-grafana.json, 内容概述如下:

{
"metricsUsed": [
":node_memory_MemAvailable_bytes:sum",
"alertmanager_alerts",
"alertmanager_alerts_invalid_total",
"alertmanager_alerts_received_total",
"alertmanager_notification_latency_seconds_bucket",
"alertmanager_notification_latency_seconds_count",
"alertmanager_notification_latency_seconds_sum",
"alertmanager_notifications_failed_total",
"alertmanager_notifications_total",
"cluster",
"cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits",
"cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests",
"cluster:namespace:pod_memory:active:kube_pod_container_resource_limits",
"cluster:namespace:pod_memory:active:kube_pod_container_resource_requests",
"cluster:node_cpu:ratio_rate5m",
"container_cpu_cfs_periods_total",
"container_cpu_cfs_throttled_periods_total",
"..."
],
"dashboards": [
{
"slug": "",
"uid": "alertmanager-overview",
"title": "Alertmanager / Overview",
"metrics": [
"alertmanager_alerts",
"alertmanager_alerts_invalid_total",
"alertmanager_alerts_received_total",
"alertmanager_notification_latency_seconds_bucket",
"alertmanager_notification_latency_seconds_count",
"alertmanager_notification_latency_seconds_sum",
"alertmanager_notifications_failed_total",
"alertmanager_notifications_total"
],
"parse_errors": null
},
{
"slug": "",
"uid": "c2f4e12cdf69feb95caa41a5a1b423d9",
"title": "etcd",
"metrics": [
"etcd_disk_backend_commit_duration_seconds_bucket",
"etcd_disk_wal_fsync_duration_seconds_bucket",
"etcd_mvcc_db_total_size_in_bytes",
"etcd_network_client_grpc_received_bytes_total",
"etcd_network_client_grpc_sent_bytes_total",
"etcd_network_peer_received_bytes_total",
"etcd_network_peer_sent_bytes_total",
"etcd_server_has_leader",
"etcd_server_leader_changes_seen_total",
"etcd_server_proposals_applied_total",
"etcd_server_proposals_committed_total",
"etcd_server_proposals_failed_total",
"etcd_server_proposals_pending",
"grpc_server_handled_total",
"grpc_server_started_total",
"process_resident_memory_bytes"
],
"parse_errors": null
},
{...}
]
}

(可选)通过 Grafana Dashboards json 文件

如果无法创建 Grafana API Token, 只要有 Grafana Dashboards json 文件, 也可以用来分析, 示例如下:

# 通过 Grafana Dashboard json 分析 Grafana 用到的指标
mimirtool analyze dashboard grafana_dashboards/blackboxexporter-probe.json
mimirtool analyze dashboard grafana_dashboards/es.json

得到的 json 结构和上一节类似, 就不赘述了.

第二步: 分析 Prometheus Alerting 和 Recording Rules 用到的指标

具体操作如下:

# (可选)通过 kubectl cp 将用到的 rule files 拷贝到本地
kubectl cp <prompod>:/etc/prometheus/rules/<releasename>-kube-prometheus-st-prometheus-rulefiles-0 -c prometheus ./kube-prometheus-stack/rulefiles/ # 通过 Prometheus rule files 分析 Prometheus Rule 用到的指标(涉及 recording rule 和 alert rules)
mimirtool analyze rule-file ./kube-prometheus-stack/rulefiles/*

结果如下 metrics-in-ruler.json:

{
"metricsUsed": [
"ALERTS",
"aggregator_unavailable_apiservice",
"aggregator_unavailable_apiservice_total",
"apiserver_client_certificate_expiration_seconds_bucket",
"apiserver_client_certificate_expiration_seconds_count",
"apiserver_request_terminations_total",
"apiserver_request_total",
"blackbox_exporter_config_last_reload_successful",
"..."
],
"ruleGroups": [
{
"namspace": "default-monitor-kube-prometheus-st-kubernetes-apps-ae2b16e5-41d8-4069-9297-075c28c6969e",
"name": "kubernetes-apps",
"metrics": [
"kube_daemonset_status_current_number_scheduled",
"kube_daemonset_status_desired_number_scheduled",
"kube_daemonset_status_number_available",
"kube_daemonset_status_number_misscheduled",
"kube_daemonset_status_updated_number_scheduled",
"..."
]
"parse_errors": null
},
{
"namspace": "default-monitor-kube-prometheus-st-kubernetes-resources-ccb4a7bc-f2a0-4fe4-87f7-0b000468f18f",
"name": "kubernetes-resources",
"metrics": [
"container_cpu_cfs_periods_total",
"container_cpu_cfs_throttled_periods_total",
"kube_node_status_allocatable",
"kube_resourcequota",
"namespace_cpu:kube_pod_container_resource_requests:sum",
"namespace_memory:kube_pod_container_resource_requests:sum"
],
"parse_errors": null
},
{...}
]
}

第三步: 分析没用到的指标

具体如下:

# 综合分析 Prometheus 采集到的 VS. (展示(Grafana Dashboards) + 记录及告警(Rule files))
mimirtool analyze prometheus --address=http://172.16.0.20:30090/ --grafana-metrics-file="metrics-in-grafana.json" --ruler-metrics-file="metrics-in-ruler.json"

说明:

  • --address=http://172.16.0.20:30090/ 为 prometheus 地址
  • --grafana-metrics-file="metrics-in-grafana.json" 为第一步得到的 json 文件
  • --ruler-metrics-file="kube-prometheus-stack-metrics-in-ruler.json" 为第二步得到的 json 文件

输出结果prometheus-metrics.json 如下:

{
"total_active_series": 270336,
"in_use_active_series": 61055,
"additional_active_series": 209281,
"in_use_metric_counts": [
{
"metric": "rest_client_request_duration_seconds_bucket",
"count": 8855,
"job_counts": [
{
"job": "kubelet",
"count": 4840
},
{
"job": "kube-controller-manager",
"count": 1958
},
{...}
]
},
{
"metric": "grpc_server_handled_total",
"count": 4394,
"job_counts": [
{
"job": "kube-etcd",
"count": 4386
},
{
"job": "default/kubernetes-ebao-ebaoops-pods",
"count": 8
}
]
},
{...}
],
"additional_metric_counts": [
{
"metric": "rest_client_rate_limiter_duration_seconds_bucket",
"count": 81917,
"job_counts": [
{
"job": "kubelet",
"count": 53966
},
{
"job": "kube-proxy",
"count": 23595
},
{
"job": "kube-scheduler",
"count": 2398
},
{
"job": "kube-controller-manager",
"count": 1958
}
]
},
{
"metric": "rest_client_rate_limiter_duration_seconds_count",
"count": 7447,
"job_counts": [
{
"job": "kubelet",
"count": 4906
},
{
"job": "kube-proxy",
"count": 2145
},
{
"job": "kube-scheduler",
"count": 218
},
{
"job": "kube-controller-manager",
"count": 178
}
]
},
{...}
]
}

第四步: 仅 keep 用到的指标

write_relabel_configs 环节配置

如果你有使用 remote_write, 那么直接在 write_relabel_configs 环节配置 keep relabel 规则, 简单粗暴.

可以先用 jp 命令得到所有需要 keep 的metric name:

jq '.metricsUsed' metrics-in-grafana.json \
| tr -d '", ' \
| sed '1d;$d' \
| grep -v 'grafanacloud*' \
| paste -s -d '|' -

输出结果类似如下:

instance:node_cpu_utilisation:rate1m|instance:node_load1_per_cpu:ratio|instance:node_memory_utilisation:ratio|instance:node_network_receive_bytes_excluding_lo:rate1m|instance:node_network_receive_drop_excluding_lo:rate1m|instance:node_network_transmit_bytes_excluding_lo:rate1m|instance:node_network_transmit_drop_excluding_lo:rate1m|instance:node_vmstat_pgmajfault:rate1m|instance_device:node_disk_io_time_seconds:rate1m|instance_device:node_disk_io_time_weighted_seconds:rate1m|node_cpu_seconds_total|node_disk_io_time_seconds_total|node_disk_read_bytes_total|node_disk_written_bytes_total|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_load1|node_load15|node_load5|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemAvailable_bytes|node_memory_MemFree_bytes|node_memory_MemTotal_bytes|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_uname_info|up

然后直接在 write_relabel_configs 环节配置 keep relabel 规则:

remote_write:
- url: <remote_write endpoint>
basic_auth:
username: <按需>
password: <按需>
write_relabel_configs:
- source_labels: [__name__]
regex: instance:node_cpu_utilisation:rate1m|instance:node_load1_per_cpu:ratio|instance:node_memory_utilisation:ratio|instance:node_network_receive_bytes_excluding_lo:rate1m|instance:node_network_receive_drop_excluding_lo:rate1m|instance:node_network_transmit_bytes_excluding_lo:rate1m|instance:node_network_transmit_drop_excluding_lo:rate1m|instance:node_vmstat_pgmajfault:rate1m|instance_device:node_disk_io_time_seconds:rate1m|instance_device:node_disk_io_time_weighted_seconds:rate1m|node_cpu_seconds_total|node_disk_io_time_seconds_total|node_disk_read_bytes_total|node_disk_written_bytes_total|node_filesystem_avail_bytes|node_filesystem_size_bytes|node_load1|node_load15|node_load5|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_MemAvailable_bytes|node_memory_MemFree_bytes|node_memory_MemTotal_bytes|node_network_receive_bytes_total|node_network_transmit_bytes_total|node_uname_info|up
action: keep

metric_relabel_configs 环节配置

如果没有使用 remote_write, 那么只能在 metric_relabel_configs 环节配置了.

以 etcd job 为例: (以 prometheus 配置为例, Prometheus Operator 请自行按需调整)

- job_name: serviceMonitor/default/monitor-kube-prometheus-st-kube-etcd/0
honor_labels: false
kubernetes_sd_configs:
- role: endpoints
namespaces:
names:
- kube-system
scheme: https
tls_config:
insecure_skip_verify: true
ca_file: /etc/prometheus/secrets/etcd-certs/ca.crt
cert_file: /etc/prometheus/secrets/etcd-certs/healthcheck-client.crt
key_file: /etc/prometheus/secrets/etcd-certs/healthcheck-client.key
relabel_configs:
- source_labels:
- job
target_label: __tmp_prometheus_job_name
- ...
metric_relabel_configs:
- source_labels: [__name__]
regex: etcd_disk_backend_commit_duration_seconds_bucket|etcd_disk_wal_fsync_duration_seconds_bucket|etcd_mvcc_db_total_size_in_bytes|etcd_network_client_grpc_received_bytes_total|etcd_network_client_grpc_sent_bytes_total|etcd_network_peer_received_bytes_total|etcd_network_peer_sent_bytes_total|etcd_server_has_leader|etcd_server_leader_changes_seen_total|etcd_server_proposals_applied_total|etcd_server_proposals_committed_total|etcd_server_proposals_failed_total|etcd_server_proposals_pending|grpc_server_handled_total|grpc_server_started_total|process_resident_memory_bytes|etcd_http_failed_total|etcd_http_received_total|etcd_http_successful_duration_seconds_bucket|etcd_network_peer_round_trip_time_seconds_bucket|grpc_server_handling_seconds_bucket|up
action: keep

不用 keep 而使用 drop

同样滴, 不用 keep 而改为使用 drop 也是可以的. 这里不再赘述.

总结

本文中,介绍了精简 Prometheus 指标的需求, 然后说明如何使用 mimirtool analyze 命令来确定Grafana Dashboards 以及 Prometheus Rules 中用到的指标。然后用 analyze prometheus 分析了展示和告警中usedunused 的活动 series,最后配置了 Prometheus 以仅 keep 用到的指标。

结合这次实战, 精简率可以达到 5 倍左右, 效果还是非常明显的. 推荐试一试. ️️️

️ 参考文档

本文由东风微鸣技术博客 EWhisper.cn 编写!

如何精简 Prometheus 的指标和存储占用的更多相关文章

  1. Qemu/Limbo/KVM镜像 最精简Linux+Wine,可运行Windows软件,内存占用不到70M,存储占用500M

    镜像特征: Alpine Edge系统 内置Wine 7.8,可运行大量Windows 软件 高度精简,内存占用仅68MB,存储占用仅500MB 完全开源 镜像说明: 用户名为root,密码为空格. ...

  2. 存储占用:Memory Map 汉化去广告版

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/storage-occupancy-memory-map-localization-to-billboards ...

  3. Prometheus自定义指标

    1.  自定义指标 为了注册自定义指标,请将MeterRegistry注入到组件中,例如: public class Dictionary { private final List<String ...

  4. prometheus搜索指标显示No datapoints found.

    在指标能够在下拉框可以选择到的情况下,还有No datapoints found. 则考虑是时区的问题,详见官方issue https://github.com/prometheus/promethe ...

  5. mysql 编码和汉字存储占用字节问题的探索

    MySql 5.5 之前,UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区,BMP是从哪到哪?基本就是 0000 ~ FFFF 这一区. 从MySQL 5.5 开始,可支持4 ...

  6. 剖析Prometheus的内部存储机制

    Prometheus有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用3.5byte左右空间,上百万条时间序列,30秒间隔,保留60天,大概花了200多G(引用官方PPT). 接下来让我们看看他 ...

  7. Prometheus存储模型分析

    Prometheus是时下最为流行的开源监控解决方案,我们可以很轻松地以Prometheus为核心快速构建一套包含监控指标的抓取,存储,查询以及告警的完整监控系统.单个的Prometheus实例就能实 ...

  8. 部署prometheus监控kubernetes集群并存储到ceph

    简介 Prometheus 最初是 SoundCloud 构建的开源系统监控和报警工具,是一个独立的开源项目,于2016年加入了 CNCF 基金会,作为继 Kubernetes 之后的第二个托管项目. ...

  9. Prometheus监控学习笔记之Prometheus存储

    0x00 概述 Prometheus之于kubernetes(监控领域),如kubernetes之于容器编排.随着heapster不再开发和维护以及influxdb 集群方案不再开源,heapster ...

  10. Prometheus监控学习笔记之prometheus的远端存储

    0x00 概述 prometheus在容器云的领域实力毋庸置疑,越来越多的云原生组件直接提供prometheus的metrics接口,无需额外的exporter.所以采用prometheus作为整个集 ...

随机推荐

  1. Merge Into 语法支持

    KINGBASE 兼容Oracle 语法,实现了merge into 的功能.以下以例子的形式,介绍merge into语法的使用.以下例子在V8R6 ,且 database_mode=oracle ...

  2. Python数据科学手册-Pandas:合并数据集

    将不同的数据源进行合并 , 类似数据库 join merge . 工具函数 concat / append pd.concat() 简易合并 合并高维数据 默认按行合并. axis=0 ,试试 axi ...

  3. github配置添加SSH秘钥

    在 github 上添加 SSH key 的步骤: 1.首先需要检查你电脑是否已经有 SSH key 运行 git Bash 客户端,输入如下代码: $ cd ~/.ssh $ ls 这两个命令就是检 ...

  4. 使用 Loki 收集 Traefik 日志

    转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247492264&idx=1&sn=f443c92664 ...

  5. 天翼云上新增IP备案具体操作步骤

    0.点击右上角的备案,进入到备案中心 1.已备案信息管理 点击左侧的已备案信息管理,右侧出现的页面中找到已备案网站信息,网站负责人后面的操作里有5个图标,点击第三个(变更接入),提交订单,进入到下一步 ...

  6. 在k8s中部署前后端分离项目进行访问的两种配置方式

    第一种方式 (1) nginx配置中只写前端项目的/根路径配置 前端项目使用的Dockerfile文件内容 把前端项目编译后生成的dist文件夹放在nginx的html默认目录下,浏览器访问前端项目时 ...

  7. 使用logstash同步Mysql数据表到ES的一点感悟

    针对单独一个数据表而言,大致可以分如下两种情况: 1.该数据表中有一个根据当前时间戳更新的字段,此时监控的是这个时间戳字段 具体可以看这个文章:https://www.cnblogs.com/sand ...

  8. MySQL集群搭建(3)-MMM高可用架构

    1 MMM 介绍 1.1 简介 MMM 是一套支持双主故障切换以及双主日常管理的第三方软件.MMM 由 Perl 开发,用来管理和监控双主复制,虽然是双主架构,但是业务上同一时间只允许一个节点进行写入 ...

  9. GitLab 之 Git LFS 大文件存储的配置

    转载自:https://cloud.tencent.com/developer/article/1010589 1.Git LFS 介绍 Git 大文件存储(Large File Storage,简称 ...

  10. 各编程语言 + aardio 相互调用示例

    代码简单.复制可用.aardio 快速调用 C,C++,C#,Java,R,V,Python,JavaScript,Node.js,Rust,PHP,Ruby,PowerShell,Fortran,D ...