iT邦幫忙

2024 iThome 鐵人賽

DAY 7
1
DevOps

時間序列資料庫探討 - Prometheus系列 第 7

Prometheus - 讀取時間序列資料的 API

  • 分享至 

  • xImage
  •  

上篇提問

  • Prometheus 提供了哪些讀介面?
  • PromQL 表達式有哪些語法?如何運行?
  • Alert Template 有哪些語法?

本篇先來回答語法以外的問題。

讀取資料的介面

本節的問題有兩個:

  • Prometheus 提供了哪些讀取時間序列資料的介面?
  • Prometheus 有哪中介資料可以讀?

除了報警系統響時可以間接得知 Prometheus 裡的資料以外,都是靠 http 來傳資料的。
相關 http API 有:

  • 遠端寫入
  • 讀取資料
    • /query
    • /query_range
    • /query_exemplars
  • 讀取中介資料
    • /labels
    • /label/:name/values
    • /series

遠端寫入

Prometheus 提供一個定時寫出資料的 http client,主要用來把資料寫到下游的資料庫如 InfluxDB、OpenTSDB、Graphite 或是其他 Prometheus。

只要依文件在設定檔裡設定好 remote_write,Prometheus 就會把資料寫出去了。

讀取資料 API

用 API 來讀取時間序資料都會用到 PromQL,PromQL 有四種運算時的中間型態,但能返回的資料型態基本只有一種。就是一個由時間序列所構成的時間序列集。
這個時間序列集可以只有一個時間序列,也可以有多個時間序列。它們都會有對應的標籤值和樣本值。
如 PromQL: api_http_responses 這個時間序列集可能包含了四個時間序列:

api_http_responses{job="apiserver", handler="/api/comments"} # 1 1 3
api_http_responses{job="apiserver", handler="/api/posts"} # 1 2 3 
api_http_responses{job="ingested", handler="/api/comments"} # 0 7 12
api_http_responses{job="ingested", handler="/api/posts"} # 2 2 4

從而 PromQL: sum(api_http_responses) by (job) 這個時間序列集包含了兩個時間序列:

{job="apiserver"} # 2 3 6
{job="ingested"} # 2 9 16

瞭解了 PromQL 返回的資料型態,就可以知道讀取資料的 API 拿 PromQL 做些什麼了。

GET /query

這個 API 一般用來讀取給定時間點下,PromQL 表達的時間序列集中,每個時間序列當時最新的樣本值。參數有:

  • query:PromQL 表達式
  • time:要查詢的時間點(預設是 Prometheus 收到 http 的時間)
  • timeout:http 超時時限

回傳資料格式是 JSON

  • status
  • data
    • resultType
    • result(陣列)
      • metric
      • value

借用文件的例子:

$ curl 'http://localhost:9090/api/v1/query?query=up&time=2015-07-01T20:10:51.781Z'
{
    "status" : "success",
        "data" : {
            "resultType" : "vector",
            "result" : [
            {
                "metric" : {
                    "__name__" : "up",
                    "job" : "prometheus",
                    "instance" : "localhost:9090"
                },
                "value": [ 1435781451.781, "1" ]
            },
            {
                "metric" : {
                    "__name__" : "up",
                    "job" : "node",
                    "instance" : "localhost:9100"
                },
                "value" : [ 1435781451.781, "0" ]
            }
            ]
        }
}

查詢名為 up 的序列集,得兩個時間序列

up{job="prometheus", instance="localhost:9090"}
up{job="node", instance="localhost:9100"}

而這兩個時間序列在查詢時間點的值分別是 10

GET /query_range

這個 API 是 /query 的加強版,也是 Grafana 監控面版用的 API。它不只查詢某個時間點的值,而是可以對一段時間內的值間隔取樣計算。參數有:

  • query:PromQL 表達式
  • start:取樣時間最小值(閉區間)
  • end:取樣時間最大值(閉區間)
  • step:取樣間隔(從 start 開始,每次加 step)
  • timeout:http 超時時限

回傳資料格式是 JSON

  • status
  • data
    • resultType
    • result(陣列)
      • metric
      • values(陣列)
        一樣借用文件的例子:
$ curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s'
{
    "status" : "success",
        "data" : {
            "resultType" : "matrix",
            "result" : [
            {
                "metric" : {
                    "__name__" : "up",
                    "job" : "prometheus",
                    "instance" : "localhost:9090"
                },
                "values" : [
                    [ 1435781430.781, "1" ],
                    [ 1435781445.781, "1" ],
                    [ 1435781460.781, "1" ]
                ]
            },
            {
                "metric" : {
                    "__name__" : "up",
                    "job" : "node",
                    "instance" : "localhost:9100"
                },
                "values" : [
                    [ 1435781430.781, "0" ],
                    [ 1435781445.781, "0" ],
                    [ 1435781460.781, "0" ]
                ]
            }
            ]
        }
}

注意到每個樣本值的時間戳記都是 http 所指定的取樣時間,而不是樣本從標的被拉到 Prometheus 的時間。step 越小,樣本值的數量就越多。如果取樣間隔遠小於 Prometheus 拉資料的間隔,回傳的樣本值就會有很多重複的,因為取樣時的樣本值都沒有變。

GET /query_exemplars

這個 API 類似 /query,但它查詢的是指標的範例值(OpenMetrics 規定加在註解的部份)。參數有:

  • query:PromQL 表達式
  • start:時間最小值(閉區間)
  • end:時間最大值(閉區間)

讀取中介資料 API

這些 API 用來讀取 Prometheus 裡的中介資料,如標籤值、標籤值的值、時間序列集。這些 API 一般用來幫助使用者查詢 Prometheus 裡有哪些時間序列,或是有哪些標籤值。

GET /series

這個 API 用來查詢 Prometheus 裡有哪些時間序列在給定時間範圍內有值。參數有:

  • match[]:時間序列的的過濾條件,可以有多個,符合其中一個就會被返回
  • start:時間最小值(閉區間)
  • end:時間最大值(閉區間)
  • limit:最多返回幾個時間序列

回傳的資料格式是 JSON。

  • status
  • data
    • resultType
    • result(陣列)
      • metric

GET /labels

/series 類似,這個 API 用來查詢 Prometheus 裡有哪些標籤。參數同上。
不同的是回傳的就只有標籤名字,而不是時間序列集。

GET /label/<標籤名>/values

這個 API 用來查詢 Prometheus 裡某個標籤名在時間範圍內有哪些值。參數亦同上。
回傳的也只有標籤值。
Grafrana 的標籤選單就是用這個 API 來查詢的。

PromQL 的計算環境

本節的問題:

  • PromQL 的計算會依賴環境嗎?

在資料不變的情況下,PromQL 所表達的時間序列集是不變的。但這裡的資料是不只是 Prometheus 的存起來的資料,還包含 PromQL 所取樣的時間點。

舉一個極端的例子,如果有一個時間序列 x 在奇數秒的值是 1,偶數秒的值是 0。那麼 PromQL: 1 / x 這個表達式就只有在奇數秒有值。
那麼 query_range?step=2&start=0.5query_range?step=2&start=1.5 這兩個查詢就會得到不同的結果。
query_range?step=2&start=0.5 會得到全部都是 1,而 query_range?step=2&start=1.5 會全部都是 +Inf。


上一篇
Prometheus - 讀取時間序列資料
下一篇
Prometheus - PromQL 語法基本
系列文
時間序列資料庫探討 - Prometheus30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言