• 对于注定会优秀的人来说,他所需要的,只是时间----博主
  • 手懒得,必受贫穷,手勤的,必得富足----《圣经》
  • 帮助别人,成就自己。愿君在本站能真正有所收获!
  • 如果你在本站中发现任何问题,欢迎留言指正!
  • 宝剑锋从磨砺出,梅花香自苦寒来!
  • 本站开启了防爆破关小黑屋机制,如果您是正常登录但被关进小黑屋,请联系站长解除!

<六>Prometheus学习笔记–从CPU的获取来学习理解查询语句

Prometheus eryajf 2周前 (02-05) 106°C 已收录 0个评论
本文预计阅读时间 14 分钟

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

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

image-20191116215845937

在我没有深入了解学习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命令,或者 tophtop)等命令进行查看,如下:

image-20191127223930493

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

image-20191127224214485

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

2,CPU详解

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

curl 127.0.0.1:9100/metrics

请求之后会返回很多的内容,这里只把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

这组数据,看最开头的两行注释,可以了解到这是一个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

注意: 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%

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

3,再回首

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

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

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

  • 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在获取一些监控指标的内容是,大体的思路与方法,当然,上边的解析还是有一些粗糙的,并没有深入讲解其中的函数,以及其他一些表现方式的含义,这些内容,自然又会单独另外一篇文章进行分析。

参考地址:


weinxin
扫码订阅本站,第一时间获得更新
微信扫描二维码,订阅我们网站的动态,另外不定时发送WordPress小技巧,你可以随时退订,欢迎订阅哦~

二丫讲梵 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明<六>Prometheus学习笔记–从CPU的获取来学习理解查询语句
喜欢 (0)
[如果想支持本站,可支付宝赞助]
分享 (0)
eryajf
关于作者:
学无止境,我愿意无止境学。书山有路,我愿意举身投火,淬炼成金!永远不要忘记,激情的奋进,就是美好的未来!

您必须 登录 才能发表评论!