二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • 最佳实践

  • 迎刃而解

  • Nginx

  • Php

  • Zabbix

  • AWS

  • Prometheus

    • Prometheus安装部署及简单监控
    • Prometheus邮件报警配置
    • Prometheus配置Grafana Dashboard
    • Prometheus 监控之 Redis
    • Prometheus 监控之 MySQL
    • 从CPU的获取来学习理解Prometheus查询语句
      • 1,引子
      • 2,关于 CPU
        • 1,问两个问题
        • 2,CPU 详解
      • 3,再回首
    • Prometheus监控之kafka集群
    • Prometheus监控之elasticsearch集群
    • Prometheus关于with和by的作用及用法
    • 利用promwrite对prometheus进行remote-write写入
    • prometheus结合nginx-lua-prometheus监控openresty
  • Grafana

  • Loki

  • CentOS

  • Supervisord

  • Systemd

  • Docker

  • Docker-Compose

  • Rancher

  • Ansible

  • OpenLdap

  • GitLab

  • GitHub

  • Etcd

  • Consul

  • RabbitMQ

  • Kafka

  • Mysql

  • MongoDB

  • OpenVPN

  • Kvm

  • VMware

  • 配置文件详解

  • Other

  • 运维观止
  • Prometheus
二丫讲梵
2020-02-05
目录

从CPU的获取来学习理解Prometheus查询语句

文章发布较早,内容可能过时,阅读注意甄别。

# 1,引子

在 prometheus 当中,如果想要查询每台服务器每 1 分钟的 CPU 负载是多少,则需要使用如下的查询语句进行查询:

(1-((sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)) /(sum(increase(node_cpu_seconds_total[1m])) by (instance)))) * 100
1

输入到查询框之后,直接回车,返回的是对应结果的 value,点击 Graph 可以看到比较简单的图,如下:

image

在我没有深入了解学习 prometheus 之前,看到这样的查询语句,早就已经蒙圈了,我也正是好多次被这样繁复的语句给吓到,从而始终没有入了 Prometheus 的门,大多时候,作为运维的我们,在习惯了 zabbix 的各种点点点就能出图的方式之后,就相对比较抵触这种像编程一样的监控方式,而且从上边截图看起来,一切也都并不那么优雅美观,于是,我们就在内心里把 Prometheus 判了死刑。

但是,如果我们真正能够放下自己内心的成见,花一些时间,用心体会了 Prometheus 的设计思路已经监控方式之后,应该会被这种细致与简洁吸引。

在 Prometheus 中,这种特有的查询方式,被称作 PromQL (Prometheus Query Language) ,PromQL 是 Prometheus 自己开发的数据查询 DSL 语言,语言表现力非常丰富,官方也提供了许多非常丰富的函数供我们使用,我们以后的监控大盘的绘制,以及告警规则的定义,都会用到它。

接下来我就先从最简单也最常见的关于 CPU 的监控说起,一步一步来探析 Prometheus 针对 exporter 暴漏出来的 metrics 是如何处理成我们想要的结果的。

# 2,关于 CPU

# 1,问两个问题

在进行真正的所谓的 CPU 负载或者使用率的查询方法介绍之前,我们不妨先想一个问题,那就是,Linux 服务器中,CPU 负载或者使用率是如何查看的呢?如果这个问题探究明白了,那么 Prometheus 当中如何查询也就不难了。

作为运维老手,我们应该都能很容易想到日常工作中,查看 CPU 的使用情况直接用 w命令,或者 top(htop)等命令进行查看,如下:

image

从上图能大概看出此时 CPU 使用率占比较高的一些进程情况,以及服务器整体 CPU 的大概情况,如果想要看每颗 CPU 的使用情况,还可以按一下 1,查看每颗的使用占比:

image

看起来刚刚的问题似乎并不复杂,监控工具采集的时候也模仿刚刚的命令即可。那么,此时或许可以再问一步,是不是可以想想,这些命令 w,top又是怎么得出的 CPU 使用百分比的呢?这个问题,才是我这里真正想要问的问题,那么,我们就带着这个问题,开启今天关于如何在 Prometheus 中查询主机 CPU 使用情况的旅程。

# 2,CPU 详解

通常在 Prometheus 当中,我们通过 node_exporter来获取主机相关的一些信息,在任意一台安装了node_exporter的主机上执行如下命令,可以查看所有的 metrics。

curl 127.0.0.1:9100/metrics
1

请求之后会返回很多的内容,这里只把 CPU 相关的摘出来,便于后边分析理解:

# HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 3.5753192e+06
node_cpu_seconds_total{cpu="0",mode="iowait"} 2862.38
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 10430.32
node_cpu_seconds_total{cpu="0",mode="softirq"} 1593.13
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 20133.98
node_cpu_seconds_total{cpu="0",mode="user"} 114790.89
node_cpu_seconds_total{cpu="1",mode="idle"} 3.53955659e+06
node_cpu_seconds_total{cpu="1",mode="iowait"} 3402
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 15018.42
node_cpu_seconds_total{cpu="1",mode="softirq"} 1084.01
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 23992.78
node_cpu_seconds_total{cpu="1",mode="user"} 139793.89
node_cpu_seconds_total{cpu="2",mode="idle"} 3.50768181e+06
node_cpu_seconds_total{cpu="2",mode="iowait"} 3373.99
node_cpu_seconds_total{cpu="2",mode="irq"} 0
node_cpu_seconds_total{cpu="2",mode="nice"} 13949.32
node_cpu_seconds_total{cpu="2",mode="softirq"} 1047.97
node_cpu_seconds_total{cpu="2",mode="steal"} 0
node_cpu_seconds_total{cpu="2",mode="system"} 22868.3
node_cpu_seconds_total{cpu="2",mode="user"} 175018.57
node_cpu_seconds_total{cpu="3",mode="idle"} 3.54823306e+06
node_cpu_seconds_total{cpu="3",mode="iowait"} 3286.86
node_cpu_seconds_total{cpu="3",mode="irq"} 0
node_cpu_seconds_total{cpu="3",mode="nice"} 14471.86
node_cpu_seconds_total{cpu="3",mode="softirq"} 996.37
node_cpu_seconds_total{cpu="3",mode="steal"} 0
node_cpu_seconds_total{cpu="3",mode="system"} 22494.83
node_cpu_seconds_total{cpu="3",mode="user"} 135483.97
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
32
33
34

这组数据,看最开头的两行注释,可以了解到这是一个 counter 类型的,记录了各个模式 (这个翻译未必准备) 所花费的时间 (一定要注意这个地方的值是一个时间的数值) 的 metrics。

有人可能会想,我就想查询一下 CPU 的使用情况,一下子整出来这么一大堆东东,都是什么鬼额,其实不用惊慌,让我们去繁就简,拨开云雾,一切就都清晰了。

首先看到 metrics 的 key 为 node_cpu_seconds_total,表示 CPU 使用时间,大括号里的内容表示对前边的 key 进行二次细分,mode 表示各个模式,CPU 表示各个 CPU(我这台机器 4 核,所以看到是 4 组),大括号外边就是 key 对应的 value 了。

那么,先去掉四分之三,剩下一组,来看单颗 CPU,仍然有八项内容,不过,只要弄明白了每个 mode 的含义,在倒推回来,理解 CPU 的使用率就不难了。

这里的 mode,与上边 top 命令中看到的,是一样的,每个 mode 对应的含义如下:

  • user(us) 表示用户态空间或者说是用户进程 (running user space processes) 使用 CPU 所耗费的时间。这是日常我们部署的应用所在的层面,最常见常用。
  • system(sy) 表示内核态层级使用 CPU 所耗费的时间。分配内存、IO 操作、创建子进程…… 都是内核操作。这也表明,当 IO 操作频繁时,System 参数会很高。
  • steal(st) 当运行在虚拟化环境中,花费在其它 OS 中的时间(基于虚拟机监视器 hypervisor 的调度);可以理解成由于虚拟机调度器将 cpu 时间用于其它 OS 了,故当前 OS 无法使用 CPU 的时间。
  • softirq(si) 从系统启动开始,累计到当前时刻,软中断时间
  • irq(hi) 从系统启动开始,累计到当前时刻,硬中断时间
  • nice(ni) 从系统启动开始,累计到当前时刻, 低优先级 (低优先级意味着进程 nice 值小于 0) 用户态的进程所占用的 CPU 时间
  • iowait(wa) 从系统启动开始,累计到当前时刻,IO 等待时间
  • idle(id) 从系统启动开始,累计到当前时刻,除 IO 等待时间以外的其它等待时间,亦即空闲时间

理论当中,下边等式是成立的:

total = user + nice + system + idle + iowait + irq + softirq + steal
1

注意: guest 以及 guest_nice 不参与求和计算,因为这两种时间分别作为 user 以及 nice 的一部分统计在其中了。

那么,正是基于如上一个等式,我们想要计算主机 CPU 的使用率的时候,只需要看看正常工作使用的时间占所有时间的比重是多少就可以了。谈到这里,基本上我们就能隐隐对这些概念有一个模糊的认识了,接着可以得出如下的一些等式:

%us=(User time + Nice time)/total * 100%
%sy=(System time + Hard Irq time +SoftIRQ time)/total * 100%
%id=(Idle time)/total * 100%
%ni=(Nice time)/total * 100%
%wa=(Waiting time)/total * 100%
%hi=(Hard Irq time)/total * 100%
%si=(SoftIRQ time)/total * 100%
%st=(Steal time)/total * 100%
1
2
3
4
5
6
7
8

现在,我们已经弄清楚了 CPU 当中一些计算的逻辑与方式,就可以倒推回去,再把一开始展示的 CPU 使用率计算公式拿出来,逐段进行解析了。

申明

原创文章eryajf,未经授权,严禁转载,侵权必究!此乃文中随机水印,敬请读者谅解。

Copyright 二丫讲梵 (opens new window) 版权所有

# 3,再回首

再回首的时候,让我再一次将开头的命令拿过来进行一下简单解析:

(1-((sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)) /(sum(increase(node_cpu_seconds_total[1m])) by (instance)))) * 100
1

现在再来理解这个计算语句就不是那么困难了,根据括号我们可以粗略将如上内容拆分成三个部分:

  • 1-((sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)):这句话从内到外进行解析,后边计算的是 1 分钟内所有 CPU 的空闲时间,前边 1 减去这个时间,得出的就是正常使用的时间。
  • (sum(increase(node_cpu_seconds_total[1m])) by (instance))):这句话表达的意思更加简单,就是计算 1 分钟内,CPU 的总时间。
  • 剩下的部分,直白说就是 使用时间 除以 总时间 再乘以 一百 最终得出 1 分钟内 CPU 的使用率。

解析完毕之后,我们大概就能理解了,Prometheus 在获取一些监控指标的内容是,大体的思路与方法,当然,上边的解析还是有一些粗糙的,并没有深入讲解其中的函数,以及其他一些表现方式的含义,这些内容,自然又会单独另外一篇文章进行分析。

  • 参考地址:
    • http://t.cn/zYJ4bT2 (opens new window)
    • http://t.cn/AikMQEea (opens new window)
微信 支付宝
#prometheus
上次更新: 2024/07/04, 22:40:37
Prometheus 监控之 MySQL
Prometheus监控之kafka集群

← Prometheus 监控之 MySQL Prometheus监控之kafka集群→

最近更新
01
学习周刊-总第212期-2025年第21周
05-22
02
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
03
学习周刊-总第211期-2025年第20周
05-15
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式