GH Page地址git
Prometheus有兩種query:instant query、range query。本文要講的就是range query中的step參數。github
range query是很是常見的一種query,看看它有哪些參數:express
query=<string>
: PromQL表達式。start=<rfc3339 | unix_timestamp>
: 時間範圍的開始。end=<rfc3339 | unix_timestamp>
: 時間範圍的結束。step=<duration | float>
: 查詢解析度(query resolution)。timeout=<duration>
: 執行超時。這個參數是可選的。在Prometheus expression browser裏看到的是這樣的:segmentfault
注意到上圖中的Res框裏沒有給值,沒有給的話Prometheus會自動給一個值,這個值在圖示右上角能夠看到。api
Prometheues在對PromQL表達式求值的邏輯是這樣的(詳見這個issue裏的回答):bash
舉例:start=10,end=20,step=2
,那麼就會有ts=10,ts=12,ts=14,ts=16,ts=18,ts=20
6段,而後爲這6個段進行求值。求值方式視乎表達式中Time series selector的類型而定。post
PromQL有兩種Time series selector:instant vector selector和range vector selector。下面將分別講解:spa
形以下面的就是Instant vector selector,x
是metric的名字。unix
x
Prometheus在對每段Instant vector selector求值的邏輯是這樣的:code
下面這張圖解釋了上面邏輯:
圖中的綠點是Prometheus實際存儲的數據,按照時間軸從左到右排列。藍點是根據step參數的求值結果。
當data point間隔比step更大的時候會發生下圖這種狀況:
能夠看到有兩個段的求值結果來自於同一個data point。
形以下面的就是Range vector selector,x
是metric的名字,方括號裏的是range duration
。
x[5m]
range vector select返回的是當前timestamp以前的range duration
內的全部data point。range vector是不能直接用作繪圖的,你得用某些function把range vector轉換成instant vector才行,好比rate()。
下圖解釋了是如何對Range vector selector進行分段求值的:
step
和range duration
是獨立的兩個參數,在某些狀況下二者的值存在某種限制條件,這裏例舉rate()來講明。rate()
的做用是得到一個range-vector的每秒平均增加率。
若是step=10m
而range duration=5m
,那麼rate
在計算的時候會丟失一半的數據,兩個分段之間的data point有一半沒有被歸入計算。前面那張圖就存在數據丟失的狀況,有一個data point被漏掉了。
所以在使用rate()
時,range duration
得大於等於step
。
而若是是irate(),這個限制則是range duration
不得大於step
(詳見Brian Brazil的Presentation)。
在Grafana中並無直接提供step
參數,而是這兩個參數:min step
和resolution
(文檔在這裏)。min step
故名思義設定的是step
的最小值,那麼resolution
是什麼呢?
你們都知道Grafana都是用來畫圖的,好比下面這張圖Y軸是值,X軸則是時間線,所以在X軸方向的每一個像素都表明了一個timestamp。
resolution
就是用來根據像素來計算step
的一個參數。下面用6個像素以及它們的timestamp來講明:
x=1,ts=0; x=2,ts=5; x=3,ts=10; x=4,ts=15; x=5,ts=20; x=6,ts=25
resolution=1/1
時,那麼step
就是相鄰像素所表明的timestamp的差,即5;resolution=1/2
時,那麼step
就是相隔1個像素的兩個像素的timestamp的差,即10;resolution=1/3
時,那麼step
就是相隔2個像素的兩個像素的timestamp的差,即15;而每一個像素所表明的timestamp受兩個因素影響:
因此在Grafana發起的查詢中step
參數是動態的。其實這也是很合理的,由於只有這樣纔可以在Graph寬度小的時候繪圖更粗糙(即step
更大),Graph寬度大的時候繪圖更精細(即step
更小,可是不能小於min step
)。實際發起的請求的step
參數你能夠在Graph的Query Inspector裏看到:
可是咱們以前不說過了rate()
的range duration
不能小於step
嗎?那麼把range duration
給固定值的化就不太好了,怎麼辦呢?你可使用Grafana提供的內置變量$__interval
,它表明的Grafana就是計算出來的step
的值。好比這樣就可以將range duration
和step
保持一致了(更多內置變量能夠見這裏):
rate(x[$__interval])
若是你想本身動手實驗,可是又苦於沒法制造乾淨的假數據,那麼能夠參考這篇文章推薦的方法。