Prometheus之PromQL基礎


一 PromQL簡介

  • Prometheus基於指標名稱(Metrics name)以及附屬的標簽集(labelset)唯一定義一條時間序列;
    • 指標名稱代表着監控目標上某類可測量屬性的基本特征標識;
    • 標簽則是這個基本特征上再次細分的多個可測量維度;
  • 基於PromQL表達式,用戶可以針對指定的特征及其細分的維度進行過濾、聚合、統計等運算從而產生期望的計算結果;
  • PromQL(Prometheus Query Language)是Prometheus Server內置數據查詢語言;
    • PromQL使用表達式(expression)來表達查詢需求;
    • 根據其使用的指標和標簽,以及時間時間范圍,表達式的查詢請求可靈活地覆蓋在一個或多個時間序列的一定范圍內的樣本之上,甚至是只包含單個時間序列的單個樣本;

二 PromQL時間序列

2.1 時間序列

時間序列數據:按照時間順序記錄系統、設備狀態變化的數據,每個數據稱為一個樣本;

  • 數據采集以特定的時間周期進行,因而,隨着時間流逝,將這些樣本數據記錄下來,將生成一個離散的樣本數據序列;
  • 改序列也稱為向量。而將多個序列放在同一個坐標系內,將形成一個有數據點組成的矩陣;

2.2 數據類型

PromQL的表達式中支持4中數據類型:

  • 即時向量(Instant Vector):特定或全部的時間序列集合上,具有相同時間戳的一組樣本值稱為即時向量;
  • 范圍向量(Range Vector):特定或全部的時間序列集合上,在指定的同一時間范圍內的所有樣本值;
  • 標量(Scalar):一個浮點型的數據值;
  • 字符串(String):支持使用單引號、雙引號或反引號進行應用,但反引號中不會對轉義字符進行轉義;

2.3 指標

  • 指標名稱和標簽的特定組合代表着一個時間序列;
    • 指標名稱相同,但標簽不同的組合分布代表着不同的時間序列;
    • 不同的指標名稱自然更是代表着不同的時間序列;
  • PromQL支持基於定義的指標維度進行過濾和聚合;
    • 更改任何標簽值,包括添加或刪除標簽,都會創建一個新的時間序列;
    • 應該盡可能地保持標簽的穩定性,否則,則很可能創建新的時間序列,更甚者會生成一個鼎泰的數據環境,並使得監控的數據源難以跟蹤,從而導致建立在該指標之上的圖形、告警及記錄規則變得無效;

三 時間序列選擇器

3.1 時間序列選擇器介紹

  • PromQL的查詢操作需要針對有限個時間序列上的樣本數據進行,挑選出目標時間序列是構建表達式最為關鍵的一步;
  • 用戶可使用向量選擇器表達式來挑選出給定指標名稱下的所有時間序列或部分時間序列的及時樣本值或至少過去某個時間范圍內的樣本值,前者稱為即時向量選擇器。后者稱為范圍向量選擇器
    • 即時向量選擇器(Instant Vector Selectors):返回0個、1個或多個時間序列上在給定時間戳上的各自的一個樣本,改樣本也可稱為即時樣本;
    • 范圍向量選擇器(Range Vector Selectors):返回0個、1個或多個時間序列上在給定時間范圍內的各自的一組樣本;

3.2 向量表達式使用要點

  • 表達式的返回值類型亦是即時向量、范圍向量、標題或字符串4中數據類型的其中之一,但是有些使用場景要求表達式返回值必須滿足特定的條件,例如
    • 需要將返回值繪制成圖形時,僅支持即時向量類型的數據;
    • 對於諸如rate一類的速度函數來說,其要求使用的卻又必須是范圍向量型的數據;
  • 由於范圍向量選擇器的返回的是范圍向量型數據,它不能用於表達式瀏覽器中圖形繪制功能,否則,表達式瀏覽器會返回“Error executing query:invalid expression type "range vector" for range query,must be Scalar or instant Vector” 一類的錯誤
    • 事實上,范圍向量選擇幾乎總是結合速率類的函數rate一同使用

3.3 匹配器

  • 匹配器用於定於標簽過濾條件,目前支持如下4種匹配操作符;
    • =:選擇與提供的字符串完全相同的標簽。
    • !=:選擇與提供的字符串不相同的標簽。
    • =~:選擇正則表達式與提供的字符串(或子字符串)相匹配的標簽。
    • !~:選擇正則表達式與提供的字符串(或子字符串)不匹配的標簽。
  • 注意事項:
    • 匹配到空標簽值的匹配器時,所有未定義標簽的時間序列同樣符合條件;
      • 例如:http_requests_total{env=""},則改指標名稱上所有未使用改標簽(env)的時間序列也符合條件,比如時間序列http_requests_total{method="get"};
    • 正則表達式將執行完全錨定機制,它需要匹配指定的標簽的整個值;
    • 向量選擇器知道要包含一個指標名稱,或者至少有一個不會匹配到空字符串的匹配器;
      • 例如,{job=""}為非法的選擇器;
    • 使用“__name__=”作為標簽名稱,還能夠對指標名稱進行過濾;
      • 例如,{__name__=~"http_requests_.*"}能夠匹配所有以“http_requests_”為前綴的所有指標;
  • 匹配示例
    • node_load1{instance="192.168.174.100"}
    • node_load1{job="prometheus-node"}
    • node_load1{job="prometheus-node",instance="192.168.174.100"}
    • node_load1{job="prometheus-node",instance!="192.168.174.100"}

3.4 即時向量選擇器

  • 即時向量選擇器由兩部分組成;
    • 指標名稱:用於限定特定指標下的時間序列,即負責過濾指標;可選;
    • 匹配器(Matcher):或稱為標簽選擇器,用於過濾時間序列上的標簽;定義在{}之中;可選;
  • 即時向量選擇器組合;
    • 僅給定指標名稱,或在標簽名稱上使用了空值的匹配器:返回給定的指標下的所有時間序列各自的即時樣本;
      • 例如,http_requests_total和http_requests_total{}的功能相同,都是用於返回http_requests_total指標下各時間序列的即時樣本;
    • 僅給定匹配器:返回所有符合給定匹配器的所有時間序列上的即時樣本;
      • 注意:這些時間序列可能會有着不用的指標名稱;
      • 例如,{job=".*",method="get"}
    • 指標名稱和匹配器的組合:返回給定的指標下的,且符合給定的標簽過濾器的所有時間序列上的即時樣本;
      • 例如:http_requests_total{method="get"}

3.5 范圍向量選擇器

  • 同即時向量選擇器的唯一不同之處在於,范圍向量選擇器需要在表達式后緊跟一個方括號[]來表達需要在時間序列上返回的樣本所處的時間范圍;
    • 時間范圍:以當前時間為基准時間點,指向過去一個特定的時間長度;例如[5m]便是值過去5分鍾之內;
  • 時間格式:一個整數后緊跟一個時間單位。例如“5m”中的“m”即時時間單位;
    • 可用的時間單位有ms(毫秒)、s(秒)、m(分鍾)、h(小時)、d(天)、w(周)和y(年);
    • 必須使用整數時間,且能夠將多個不同級別的單位進行串聯組合,以時間單位由大到小為順序,例如1h30m,但不能使用1.5h;
  • 需要注意的是,范圍向量選擇器返回的是一定時間范圍內的數據樣本,雖然不同時間序列的數據抓取的時間點相同,但他們的時間戳並不會嚴格對齊;
    • 多個Target上的數據抓取需要分散在抓取時間點前后一定的時間范圍內,以均衡Prometheus Server的負載;
    • 因而,Prometheus在趨勢上准確,但並非絕對精確;

3.6 偏移量修改器

  • 默認情況下,即時向量選擇器和范圍向量選擇器都已當前時間為基准時間點,而偏移量修改器能修改該基准;
  • 偏移量修改器的使用方法是緊跟在選擇器表達式之后使用“offset”關鍵字指定;
    • “http_requests_total offset 5m”,標識獲取以http_requests_total為指定名稱的所有時間序列在過去5分鍾之前的即時樣本;
    • “http_requests_total[5m] offset 1d”,表示獲取距此刻1天時間之前的5分鍾之內的所有樣本;

四 Prometheus指標類型

Prometheus Server並不使用類型信息,而是將所有數據展平為時間序列;

Prometheus有4個指標類型,它們主要由Prometheus的客戶端使用;

4.1 Counter

  • Counter:計數器,單調遞增,除非重置(例如服務器或進程重啟);
  • 通常,Counter的總數並沒有直接作用,而是需要借助於rate、topk、increase和irate等函數來生成樣本數據的變化狀況(增長率);
    • rate(http_requests_total[2h]),獲取2小時內,該指標下各時間序列上的http總請求數的增長速率;
    • topk(3,http_requests_total),獲取該指標下http請求總數排名前3的時間序列;
    • irate(http_requests_total[2h]),高靈敏度函數,用於計算指標的瞬時速率;
      • 基於樣本范圍內的最后兩個樣本進行計算,相較於rate函數來說,irate更適用於短期時間范圍內的變化速率分析;

4.2 Gauge

Gauge用於存儲其值可增可減的指標的樣本數據,常用於進行求和、取平均值、最小值、最大值等聚合計算;也經常會結合PromQL的predict_linear和dalta函數使用;

  • predict_linear(v range-vector,t,scalar)函數可以預測時間序列v在t秒后的值,它通過線性回歸的方式來預測樣本數據的Ganuge變化趨勢;
  • dalta(v range-vector)函數計算范圍向量中每個時間序列元素的第一個值與最后一個值之差,從而展示不同時間點上的樣本的差值;
    • dalta(cpu_temp_celsius{host="web01.wgs.com"}[2h]),返回服務器的CPU溫度與2小時之前的差異;

4.3 Histogram

  • Histogram是一種對數據分布情況的圖形表示,由一系列高度不等的長條圖(bar)或線段表示,用於展示單個測度的值的分布;
    • 它一般用橫軸表示某個指標維度的數據取值區間,用縱軸表示樣本統計的頻率或頻數,從而能夠以二維圖的形式展現數值的分布狀況;
    • 為了構建Histogram,首先需要將值的范圍進行分段,即將所有值的整個可用范圍分成一系列連續、相鄰但不重疊的間隔,而后統計每個間隔中有多少值;
    • 從統計學的角度看,分位數不能被聚合,也不能進行算術運算;
  • 對於Prometheus來說,HIstogram會在一段時間范圍內對數據進行采樣(通常是請求持續時間或響應大小等),並將其計入可配置的bucket中;
    • Histogram事先將特定測度可能地取值范圍分割成多個樣本空間,並通過對落入bucket內的觀測值進行計數以及求和操作;
    • 與常規方式略有不同的是,Prometheus取值間隔的划分采用的累積(Cumulative)區間間隔機制,即每個bucket中的樣本均包含了其前面所有bucket中的樣本,因而也稱為累積直方圖;
      • 可降低HIstogram的維護成本
      • 支持粗略計算樣本值的分位數
      • 單獨提供了_sum和_count指標,從而支持計算平均值
  • HIstogram類型的每個指標有一個基礎指標名稱<basename>,它會提供多個時間序列:
    • <basename>_bucket{le="<upper inclusive bound>"}:觀測桶的上邊界(upper inclusive bound),即樣本統計區間,最大區間(包含所有樣本)的名稱為<basename>_bucket{le="+Inf"}
    • <basename>_sum:所有樣本觀測值的總和;
    • <basename>_count:總的觀測次數,它自身本質上是一個Counter類型的指標;
  • 累積間隔機制生成的樣本數據需要額外使用內置的histogram_quantile()函數即可根據Histogram指標來計算響應的分數位(quantile),即某個bucket的樣本數在所有樣本數中占據的比例;
    • histogram_quantile()函數在計算分位數時會假定每個區間內的樣本滿足線性分布狀態,因而它的結果僅是一個預估值,並不完全准確;
    • 預估的准確度取決於bucket區間划分的粒度;粒度越大,准確度越低;

4.4 Summary

  • 指標類型是客戶端庫的特性,而Histogram在客戶端僅是簡單的桶划分和分桶計數,分位數計算由Prometheus Server基於樣本數據進行估算,因而其結果未必准確,甚至不合理的bucket划分會導致較大的誤差;
  • Summary是一種類似於Histogram的指標類型,但它在客戶端於一段時間內(默認為10分鍾)的每個采樣點進行統計,計算並存儲了分位數數值,Server端直接抓取響應值即可;
  • 但Summary不支持sum或avg一類的聚合運算,而且其分位數由客戶端計算並生成,Server端無法獲取客戶端未定義的分位數,而Histogram可通過PromQL任意定義,有着較好的靈活性;
  • 對於每個指標,Summary以指標名稱<basename>為前綴,生成如下幾個指標序列;
    • <basename>{quantile="<>"}
    • <basename>_sum,抓取到的所有樣本值之和;
    • <basename>_count,抓取到的所有樣本總數;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM