參考鏈接:https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql
探索PromQL
通過PromQL用戶可以非常方便地對監控樣本數據進行統計分析,PromQL支持常見的運算操作符,同時PromQL中還提供了大量的內置函數可以實現對數據的高級處理。當然在學習PromQL之前,用戶還需要了解Prometheus的樣本數據模型。PromQL作為Prometheus的核心能力除了實現數據的對外查詢和展現,同時告警監控也是依賴PromQL實現。
Metrics類型
Prometheus定義了4中不同的指標類型:
- Counter(計數器):只增不減的計數器,常見的監控指標,如http_requests_total,node_cpu都是Counter類型的監控指標。
- Gauge(儀表盤):可增可減的儀表盤,Gauge類型的指標側重於反應系統的當前狀態。因此這類指標的樣本數據可增可減。常見指標如:node_memory_MemFree(主機當前空閑的內容大小)、node_memory_MemAvailable(可用內存大小)都是Gauge類型的監控指標。
- Histogram(直方圖):主要用於統計和分享樣本的分布情況。Histogram通過histogram_quantile函數是在服務器端計算的分位數。
- Summary(摘要):主要用於統計和分享樣本的分布情況。Sumamry的分位數則是直接在客戶端計算完成。
初識PromQL
Prometheus通過指標名稱(metrics name)以及對應的一組標簽(labelset)唯一定義一條時間序列。指標名稱反映了監控樣本的基本標識,而label則在這個基本特征上為采集到的數據提供了多種特征維度。用戶可以基於這些特征維度過濾,聚合,統計從而產生新的計算后的一條時間序列。
查詢時間序列
PromQL還支持用戶根據時間序列的標簽匹配模式來對時間序列進行過濾,目前主要支持兩種匹配模式:完全匹配和正則匹配。
PromQL支持使用=和!=兩種完全匹配模式:
- 通過使用label=value可以選擇那些標簽滿足表達式定義的時間序列
- 反之使用label!=value則可以根據標簽匹配排除時間序列
PromQL還可以支持使用正則表達式作為匹配條件,多個表達式之間使用 | 進行分離
- 使用label=~regx表示選擇那些標簽符合正則表達式定義的時間序列
- 反之使用label!~regx進行排除
例如:如果想查詢多個環節下的時間序列可以使用如下表達式:
http_requests_total{environment=~"staging|testing|development",method!="GET"}
范圍查詢
直接通過類似於PromQL表達式httprequeststotal查詢時間序列時,返回值中只會包含時間序列中的最新的一個樣本值,這樣的返回結果我們稱之為瞬時向量。而相應的這樣的表達式稱之為瞬時向量表達式。
而如果我們想要過去一段時間范圍內的樣本數據時,我們則需要使用區間向量表達式。區間向量表達式和瞬時向量表達式之間的差異在於在區間向量表達式中我們需要定義時間選擇的范圍,時間范圍通過時間范圍選擇器 [] 進行定義。
例如:通過以下表達式可以選擇最近5分鍾內的所有樣本數據:
http_request_total{}[5m]
除了使用m表示分鍾以外,PromQL的時間范圍選擇器支持其他時間單位:
- s - 秒
- m - 分鍾
- h - 小時
- d - 天
- w - 周
- y - 年
時間位移操作
在瞬時向量表達式或者區間向量表達式中,都是以當前時間為基准:
http_request_total{} # 瞬時向量表達式,選擇當前最新的數據 http_request_total{}[5m] # 區間向量表達式,選擇以當前時間為基准,5分鍾內的數據
而如果我們想查詢,5分鍾前的瞬時樣本數據,或昨天一天的區間內的樣本數據呢?這個時候我們就可以使用位移操作,位移操作的關鍵字為offset。
例如:
http_request_total{} offset 5m http_request_total{}[1d] offset 1d
使用聚合操作
一般來說,如果描述樣本特征的標簽(label)在並非唯一的情況下,通過PromQL查詢數據,會返回多條滿足這些特征維度的時間序列。而PromQL提供的聚合操作可以用來對這些時間序列進行處理,形成一條新的時間序列:
# 查詢系統所有http請求的總量 sum(http_request_total) # 按照mode計算主機CPU的平均使用時間 avg(node_cpu) by (mode) # 按照主機查詢各個主機的CPU使用率 sum(sum(irate(node_cpu{mode!='idle'}[5m])) / sum(irate(node_cpu[5m]))) by (instance)
PromQL操作符
使用PromQL除了能夠方便的按照查詢和過濾時間序列以外,PromQL還支持豐富的操作符,用戶可以使用這些操作符進一步對事件序列進行二次加工,這些操作符包括:數學運算符,邏輯運算符,布爾運算等。
數學運算
PromQL支持的所有數學運算符如下所示:
- +(加法)
- - (減法)
- * (乘法)
- / (除法)
- %(求余)
- ^(冪運算)
使用布爾運算過濾時間序列
- ==(相等)
- !=(不相等)
- >(大於)
- <(小於)
- >=(大於等於)
- <=(小於等於)
使用bool修飾符改變布爾運算符的行為
布爾運算符的默認行為是對時序數據進行過濾。而在其它的情況下我們可能需要的是真正的布爾結果。例如,只需要知道當前模塊的HTTP請求量是否>=1000,如果大於等於1000則返回1(true)否則返回0(false)。這時可以使用bool修飾符改變布爾運算的默認行為。 例如:
http_requests_total > bool 1000
使用bool修改符后,布爾運算不會對時間序列進行過濾,而是直接依次瞬時向量中的各個樣本數據與標量的比較結果0或者1。從而形成一條新的時間序列。
使用集合運算符
使用瞬時向量表達式能夠獲取到一個包含多個時間序列的集合,我們稱為瞬時向量。 通過集合運算,可以在兩個瞬時向量與瞬時向量之間進行相應的集合操作。目前,Prometheus支持以下集合運算符:
- and(並且)
- or(或者)
- unless(排除)
vector1 and vector2 會產生一個由vector1的元素組成的新的向量。該向量包含vector1中完全匹配vector2中的元素組成。
vector1 or vector2 會產生一個新的向量,該向量包含vector1中所有的樣本數據,以及vector2中沒有與vector1匹配到的樣本數據。
vector1 unless vector2 會產生一個新的向量,新向量中的元素由vector1中沒有與vector2匹配的元素組成。
操作符優先級
- ^
- * / %
- + -
- == != <= < >= >
- and unless
- or
PromQL聚合操作
Prometheus還提供了下列內置的聚合操作符,這些操作符作用域瞬時向量。可以將瞬時表達式返回的樣本數據進行聚合,形成一個新的時間序列。
- sum(求和)
- min(最小值)
- max(最大值)
- avg(平均值)
- stddev(標准差)
- stdvar(標准差異)
- count(計數)
- count_values(對value進行計數)
- bottomk(后n條時序)
- topk(前n條時序)
- quantile(分布統計)
使用聚合操作的語法如下:
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
其中只有count_values, quantile, topk, bottomk支持參數(parameter)。
without用於從計算結果中移除列舉的標簽,而保留其它標簽。by則正好相反,結果向量中只保留列出的標簽,其余標簽則移除。通過without和by可以按照樣本的問題對數據進行聚合。