天天看點

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

計算Counter名額增長率

我們知道Counter類型的監控名額其特點是隻增不減,在沒有發生重置(如伺服器重新開機,應用重新開機)的情況下其樣本值應該是不斷增大的。為了能夠更直覺的表示樣本資料的變化劇烈情況,需要計算樣本的增長速率。

如下圖所示,樣本增長率反映出了樣本變化的劇烈程度:

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

increase(v range-vector)函數是PromQL中提供的衆多内置函數之一。其中參數v是一個區間向量,increase函數擷取區間向量中的第一個和最後一個樣本并傳回其增長量。是以,可以通過以下表達式Counter類型名額的增長率:

increase(node_cpu[2m]) / 120      

這裡通過node_cpu[2m]擷取時間序列最近兩分鐘的所有樣本,increase計算出最近兩分鐘的增長量,最後除以時間120秒得到node_cpu樣本在最近兩分鐘的平均增長率。并且這個值也近似于主機節點最近兩分鐘内的平均CPU使用率。

除了使用increase函數以外,PromQL中還直接内置了rate(v range-vector)函數,rate函數可以直接計算區間向量v在時間視窗内平均增長速率。是以,通過以下表達式可以得到與increase函數相同的結果:

rate(node_cpu[2m])      

需要注意的是使用rate或者increase函數去計算樣本的平均增長速率,容易陷入“長尾問題”當中,其無法反應在時間視窗内樣本資料的突發變化。

為了解決該問題,PromQL提供了另外一個靈敏度更高的函數irate(v range-vector)。irate同樣用于計算區間向量的計算率,但是其反應出的是瞬時增長率。irate函數是通過區間向量中最後兩個樣本資料來計算區間向量的增長速率。這種方式可以避免在時間視窗範圍内的“長尾問題”,并且展現出更好的靈敏度,通過irate函數繪制的圖示能夠更好的反應樣本資料的瞬時變化狀态。

irate(node_cpu[2m])      

irate函數相比于rate函數提供了更高的靈敏度,不過當需要分析長期趨勢或者在告警規則中,irate的這種靈敏度反而容易造成幹擾。是以在長期趨勢分析或者告警中更推薦使用rate函數。

變化率

 通常來說直接繪制一個原始的 ​

​Counter​

​​ 類型的名額資料用處不大,因為它們會一直增加,一般來說是不會去直接關心這個數值的,因為 ​

​Counter​

​ 一旦重置,總計數就沒有意義了,比如我們直接執行下面的查詢語句:

demo_api_request_duration_seconds_count{job="demo"}      

可以得到下圖所示的圖形:

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

可以看到所有的都是不斷增長的,一般來說我們更想要知道的是 Counter 名額的變化率,PromQL 提供了不同的函數來計算變化率。

rate

用于計算變化率的最常見函數是 ​

​rate()​

​​,​

​rate()​

​ 函數用于計算在指定時間範圍内計數器平均每秒的增加量。因為是計算一個時間範圍内的平均值,是以我們需要在序列選擇器之後添加一個範圍選擇器。

例如我們要計算 ​

​demo_api_request_duration_seconds_count​

​ 在最近五分鐘内的每秒平均變化率,則可以使用下面的查詢語句:

rate(demo_api_request_duration_seconds_count[5m])      

可以得到如下所示的圖形:

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

現在繪制的圖形看起來顯然更加有意義了,進行 rate 計算的時候是選擇指定時間範圍下的第一和最後一個樣本進行計算,下圖是表示瞬時計算的計算方式:(現在時間點樣本值是166,往回推一分鐘,假設一分鐘内有6個樣本資料,目前去計算的時候就是目前時間點樣本值和一分鐘前時間點樣本值之間內插補點,然後一分鐘時長,相除就是目前這個點的變化率)

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

往往我們需要的是繪制一個圖形,那麼就需要進行區間查詢,指定一個時間範圍内進行多次計算,将結果串聯起來形成一個圖形:graph展示的是區間向量 

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

對于 ​

​rate()​

​ 和相關函數有幾個需要說明的:

  • 當被抓取名額進的程重新開機時,​

    ​Counter​

    ​​ 名額可能會重置為 0,但​

    ​rate()​

    ​​ 函數會自動處理這個問題,它會假設​

    ​Counter​

    ​名額的值隻要是減少了就認為是被重置了,然後它可以調整後續的樣本,例如,如果時間序列的值為​

    ​[5,10,4,6]​

    ​​,則将其視為​

    ​[5,10,14,16](會将前面的值加上)​

    ​。
  • 變化率是從指定的時間範圍下包含的樣本進行計算的,需要注意的是這個時間視窗的邊界并不一定就是一個樣本資料,可能會不完全對齊,是以,即使對于每次都是增加整數的​

    ​Counter​

    ​,也可能計算結果是非整數。
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

另外我們需要注意當把 ​

​rate()​

​​ 與一個聚合運算符(例如 ​

​sum()​

​)或一個随時間聚合的函數(任何以 ​

​_over_time​

​​ 結尾的函數)結合起來使用時,總是先取用 ​

​rate()​

​​ 函數,然後再進行聚合,否則,當你的目标重新啟動時,​

​rate()​

​ 函數無法檢測到 Counter 的重置。(因為對于counter來說數值可能是被重置了,要先用rate對其進行修複,sum對值不會進行處理,是以先去用rate進行計算,再使用sum去聚合)

注意:​

​rate()​

​​ 函數需要在指定視窗下至少有兩個樣本才能計算輸出。一般來說,比較好的做法是選擇範圍視窗大小至少是抓取間隔的​

​4​

​倍,也就是至少需要4個樣本資料點,這樣即使在遇到視窗對齊或抓取故障時也有可以使用的樣本進行計算,例如,對于 1 分鐘的抓取間隔,你可以使用 4 分鐘的 Rate 計算,但是通常将其四舍五入為 5 分鐘。是以如果使用 ​

​query_range​

​ 區間查詢(dashboard graph界面查詢),例如在繪圖中,那麼範圍應該至少是步長的大小,否則會丢失一些資料。

irate  瞬時增長📈率(反應樣本資料的瞬時變化狀态)

由于使用 rate 或者 increase 函數去計算樣本的平均增長速率,容易陷入長尾問題當中,其無法反應在時間視窗内樣本資料的突發變化。

例如,對于主機而言在 2 分鐘的時間視窗内,可能在某一個由于通路量或者其它問題導緻 CPU 占用 100%的情況,但是通過計算在時間視窗内的平均增長率卻無法反應出該問題。(現在突然CPU就達到了100%,由于圖形上面看到的是平均值,就将比較高的給拉低了,在圖形上面就看不出突然升高的情況的)

 為了解決該問題,PromQL 提供了另外一個靈敏度更高的函數​

​irate(v range-vector)​

​。irate 同樣用于計算區間向量的計算率,但是其反應出的是瞬時增長率。

irate 函數是通過區間向量中最後兩個樣本資料來計算區間向量的增長速率(rate是指定區間範圍内,比如5m鐘,是目前樣本值和五分鐘前的第一個樣本之間的內插補點再去除以5求得的變化率,irate是時間範圍内的最後兩個樣本內插補點)。

這種方式可以避免在時間視窗範圍内的長尾問題,并且展現出更好的靈敏度,通過 irate 函數繪制的圖示能夠更好的反應樣本資料的瞬時變化狀态。

那既然是使用最後兩個點計算,那為什麼還要指定類似于 ​

​[1m]​

​​ 的時間範圍呢?這個 ​

​[1m]​

​​ 不是用來計算的,irate 在計算的時候會最多向前在 ​

​[1m]​

​​ 範圍内找點,如果超過 ​

​[1m]​

​ 沒有找到資料點,這個點的計算就放棄了。

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

irate函數計算公式為: (最後兩個樣本內插補點 / 兩個樣本的間隔時間)上面是有6個樣本,每個樣本之間的時間間隔為10。 

由于 ​

​rate()​

​ 提供了更平滑的結果,是以在長期趨勢分析或者告警中更推薦使用 rate 函數,因為當速率隻出現一個短暫的峰值時,不應該觸發該報警。

使用 ​

​irate()​

​ 函數上面的表達式會出現一些短暫下降的圖形:

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

​increase​

​​  ​

​deriv predict_linear​

除了計算每秒速率,你還可以使用 ​

​increase()​

​ 函數查詢指定時間範圍内的總增量,它基本上相當于速率乘以時間範圍選擇器中的秒數:

increase(demo_api_request_duration_seconds_count{job="demo"}[1h])      
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

比如上面表達式的結果和使用 ​

​rate()​

​​ 函數計算的結果整體圖形趨勢都是一樣的,隻是 Y 軸的資料不一樣而已,一個表示數量,一個表示百分比。​

​rate()​

​​、​

​irate()​

​​ 和 ​

​increase()​

​​ 函數隻能輸出非負值的結果,對于跟蹤一個可以上升或下降的值的名額(如溫度、記憶體或磁盤空間),可以使用 ​

​delta()​

​​ 和 ​

​deriv()​

​ 函數來代替。

​deriv()​

​​ 函數可以計算一個區間向量中各個時間序列二階導數,使用簡單線性回歸,​

​deriv(v range-vector)​

​ 的參數是一個區間向量,傳回一個瞬時向量,這個函數一般隻用在 Gauge 類型的時間序列上。例如,要計算在 15 分鐘的視窗下,每秒鐘磁盤使用量上升或下降了多少:

PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

還有另外一個 ​

​predict_linear()​

​​ 函數可以預測一個 ​

​Gauge​

​ 類型的名額在未來指定一段時間内的值,例如我們可以根據過去 15 分鐘的變化情況,來預測一個小時後的磁盤使用量是多少,可以用如下所示的表達式來查詢:

predict_linear(demo_disk_usage_bytes{job="demo"}[15m], 3600)      
PromQL 平均增長率 rate 函數 瞬時增長率 irate函數 隻針對counter名額類型

這個函數可以用于報警,告訴我們磁盤是否會在幾個小時候内用完。

總結 rate vs irate

  • irate取的是在指定時間範圍内的最近兩個資料點來算速率
  • rate會取指定時間範圍内所有資料點,算出一組速率,然後取平均值作為結果。

繼續閱讀