Prometheus強大的地方就在於可以它可以使用的很多計算公式去獲取自己需要的數據。這裏所涉及到的計算公式,也是我們普遍認爲的難點所在。在Zabbix中想要獲取CPU使用率是一件非常簡單的事情,但是在Prometheus中卻需要通過計算公式來完成CPU使用率的計算。
如果要統計CPU的使用:node_exporter會抓取CPU常用你的8種狀態的累計工作時間,然後再用(所有非空閒狀態的CPU時間總和)/(所有狀態的CPU時間總和)= CPU使用率。而如果想要獲取中間某一分鐘的CPU使用時間還需要用到Counter數據類型。由於Counter的數據一致是增量,所以需要截取其中一段增量值,然後再拿這個值去套用公式進行計算。
一、常用函數
Prometheus爲不同的數據提供了非常多的計算函數,其中有個小技巧就是遇到counter數據類型,在做任何操作之前,先套上一個rate()或者increase()函數。下面是一些比較常用的函數:
1、rate函數
rate() 函數是專門搭配counter數據類型使用函數,功能是取counter在這個時間段中平均每秒的增量。
例如:獲取eth0網卡1m內每秒流量的平均值
rate(node_network_receive_bytes_total{device="eth0"}[1m])
2、increase函數
increase() 函數表示某段時間內數據的增量
rate() 函數則表示某段時間內數據的平均值
兩個函數如何選取使用?
當我們獲取數據比較精細的時候 類似於1m取樣推薦使用rate()
當我們獲取數據比較粗糙的時候 類似於5m,10m甚至更長時間取樣推薦使用increase()
例如:獲取eth0網卡1m內流量的增量
increase(node_network_receive_bytes_total{device="eth0"}[1m])
3、sum函數
sum()函數就是求和函數,注意點是當你使用sum後是將所有的監控的服務器的值進行取和,所以當我們只看某一臺時需要進行拆分
拆分常用方法:
- by increase()
- 2 by (cluster_name) 屬於自定義標籤不是標準標籤,我們可以手動將不痛功能的服務器進行分組展示
例如:獲取所有主機eth0網卡1m內每秒流量的平均值的和
sum(rate(node_network_receive_bytes_total{device="eth0"}[1m]))
4、topk函數
topk() 函數的定義是:取前面x位的最高值,最簡單理解就是數學的top3 ,當我們有很多服務器我們想要獲取某個key的數據排在前3位的服務器。
Gauge類型使用方式:
topk(3,key)
Counter類型使用方式
topk(3,rate(key[1m]))
注意:此種函數獲得數據並不是很適用圖形化展示
5、count函數
count() 是找出當前或者歷史數據中某個key的數值大於或小於某個值的統計,
例如:
count(node_netstat_Tcp_CurrEstab >50)
6、irate函數
irate(v range-vector)
計算範圍向量中時間序列的每秒即時增長率。這基於最後兩個數據點。單調性中斷(例如由於目標重啓而導致的計數器重置)會自動調整
例如:5m內http請求的每秒速率
irate(http_requests_total{job="linux-01"}[5m])
irate
只應在繪製易失性快速移動計數器時使用。使用rate
警報和緩慢移動的櫃檯,因爲在房價短暫變化可以重設FOR
條款和圖表完全由罕見尖峯難以閱讀。
注意,當irate()
與 聚合運算符(例如sum()
)或隨時間聚合的函數(以任何結尾的函數_over_time
)組合時,總是先取irate()
第一個,然後聚合。否則irate()
在目標重啓時無法檢測到計數器重置。
二、CPU使用率的計算方法
1、CPU模式
一顆CPU要通過分時複用的方式運行於不同的模式中,這些模式可以用我們常用的top
命令進行查看,其中包括:
- us:用戶進程使用cpu的時間
- sy:內核進程使用cpu的時間
- ni:用戶進程空間內改變過優先級的進程使用的cpu時間
- id:空閒(沒人用)的cpu時間
- wa:等待io的cpu時間
- hi:硬中斷的cpu時間
- si:軟中斷的cpu時間
- st:虛擬機管理程序使用的cpu時間
這些時間加在一起是總的cpu時間。
2、CPU時間
通過node-exporter
抓取的指標中cpu相關主要是各個node_cpu_seconds_total
,可以通過如下的方式查看所有的metrics。
curl http://localhost: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"} 26659.41
node_cpu_seconds_total{cpu="0",mode="iowait"} 4.79
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 0
node_cpu_seconds_total{cpu="0",mode="softirq"} 2.69
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 31.65
node_cpu_seconds_total{cpu="0",mode="user"} 8.67
node_cpu_seconds_total{cpu="1",mode="idle"} 26634.43
node_cpu_seconds_total{cpu="1",mode="iowait"} 54.14
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 0.02
node_cpu_seconds_total{cpu="1",mode="softirq"} 1.23
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 34.07
node_cpu_seconds_total{cpu="1",mode="user"} 9
node_cpu_seconds_total{cpu="2",mode="idle"} 26629.89
node_cpu_seconds_total{cpu="2",mode="iowait"} 6.57
node_cpu_seconds_total{cpu="2",mode="irq"} 0
node_cpu_seconds_total{cpu="2",mode="nice"} 0
node_cpu_seconds_total{cpu="2",mode="softirq"} 1.95
node_cpu_seconds_total{cpu="2",mode="steal"} 0
node_cpu_seconds_total{cpu="2",mode="system"} 24.66
node_cpu_seconds_total{cpu="2",mode="user"} 7.2
node_cpu_seconds_total{cpu="3",mode="idle"} 26699.96
node_cpu_seconds_total{cpu="3",mode="iowait"} 5.72
node_cpu_seconds_total{cpu="3",mode="irq"} 0
node_cpu_seconds_total{cpu="3",mode="nice"} 0.01
node_cpu_seconds_total{cpu="3",mode="softirq"} 1.27
node_cpu_seconds_total{cpu="3",mode="steal"} 0
node_cpu_seconds_total{cpu="3",mode="system"} 22.32
node_cpu_seconds_total{cpu="3",mode="user"} 7.33
上面的某一行就是某一核cpu的某個模式的運行時間,單位是秒
。把某一核各個模式的cpu時間加起來就是執行uptime得到的系統開機以來運行運行的總的秒數了。例如:
node_cpu_seconds_total{cpu="0",mode="idle"} 26659.41
這個值的意思是從系統開機到現在爲止,cpu0的空閒時間是26659.41秒。用它除以uptime就是開機以來cpu0的空閒率。
3、推導CPU使用率的公式
1)cpu0 5分鐘內處於空閒狀態的時間
increase(node_cpu_seconds_total{cpu="0",mode="idle"}[5m])
increase
表示增量,所以這個公式表示的是當前時間點的node_cpu_seconds_total
減去5分鐘之前的node_cpu_seconds_total
的值,也就是這5分鐘內處於idle
狀態的cpu時間。
2)cpu0 5分鐘內處於空閒狀態的時間佔比:
increase(node_cpu_seconds_total{cpu="0",mode="idle"}[5m]) / increase(node_cpu_seconds_total{cpu="0"}[5m])
3)一臺主機所有cpu 5分鐘內處於空閒狀態的時間佔比:
sum (increase(node_cpu_seconds_total{mode="idle"}[5m])) / sum (increase(node_cpu_seconds_total{mode="idle"}[5m]))
4)如果 Prometheus 監控多臺主機,要根據每臺主機做 sum:
sum (increase(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) / sum (increase(node_cpu_seconds_total[5m])) by (instance)
5)cpu使用率 = 1 - cpu空閒率
100 * (1 - sum (increase(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) / sum (increase(node_cpu_seconds_total[5m])) by (instance))
6)根據irate()函數,可以簡化計算公式爲:
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
三、常用計算公式
1、CPU使用率
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
2、空閒內存剩餘率
(node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100
3、內存使用率
100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100
4、磁盤使用率
100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs"} / node_filesystem_size_bytes{mountpoint="/",fstype=~"ext4|xfs"} * 100)
參考文章:
http://www.linuxe.cn/post-503.html
http://www.luyixian.cn/news_show_304303.aspx
https://my.oschina.net/54188zz/blog/3070582