iT邦幫忙

2024 iThome 鐵人賽

DAY 11
1
DevOps

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

Prometheus - Client 函式庫

  • 分享至 

  • xImage
  •  

上篇提問

  • Prometheus 有寫入時間序列相關的介面?
  • Prometheus 拉到資料後的處理有哪些?
  • 時間序列資料如何壓縮?

本篇要來回答寫入介面相關的兩個問題。

  • Prometheus Client 函式庫有哪些功能要求?
  • Push Gateway 如何使用?

Prometheus Client 函式庫的功能

Prometheus Client 函式庫主要是實作一個 http handler,提供 /metrics。這個 http handler 會有一個登錄表(Registry),可以登錄許多 Collector(不同型態的指標)。這個 handler 做得事情就是把登錄表裡的所有指標資料的值串接起來,回傳給 Prometheus。
由於 python 有各種 GIL 和 Singleton 我們看不到一些預設參數,不適合用於舉例,所以這裡用官方文件的 Go 範例來說明。
建立一個沒有任何指標的 http handler:

package main

import (
        "net/http"

        "github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
        http.Handle("/metrics", promhttp.Handler())
        http.ListenAndServe(":2112", nil)
}

其中 promhttp.Handler() 內是

func Handler() http.Handler {
	return InstrumentMetricHandler(
		prometheus.DefaultRegisterer, HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}),
	)
}

有一個 DefaultRegisterer 就是預設的登錄表。
之後登錄在 DefaultRegisterer 下的 Collector(Counter, Gauge, Histogram, Summary)指標變化就會反應在 http response 裡。

package main

import (
        "net/http"
        "time"

        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promauto"
        "github.com/prometheus/client_golang/prometheus/promhttp"
)

func recordMetrics() {
        go func() {
                for {
                        opsProcessed.Inc()
                        time.Sleep(2 * time.Second)
                }
        }()
}

var (
        opsProcessed = promauto.NewCounter(prometheus.CounterOpts{
                Name: "myapp_processed_ops_total",
                Help: "The total number of processed events",
        })
)

func main() {
        recordMetrics()

        http.Handle("/metrics", promhttp.Handler())
        http.ListenAndServe(":2112", nil)
}

這樣就可以在 http://localhost:2112/metrics 看到指標資料了。

Golang 的 Prometheus Client 提供四種 Collector(相當於指標族)型態,能夠:

  • Counter:累加器,只能增加。
    • Inc():增加 1。
    • Add(float64):增加指定數值。
  • Gauge:量表,可以增加或減少。
    • Inc():增加 1。
    • Dec():減少 1。
    • Add(float64):增加指定數值。
    • Sub(float64):減少指定數值。
    • Set(float64):設定為指定數值。
    • SetToCurrentTime():設定為當前時間。
  • Histogram:直方圖,用來計算資料的分佈,需手動指定每個直條的範圍。
    • Observe(float64):記錄一個樣本。
  • Summary:摘要,用來估算特定百分位的值。
    • Observe(float64):記錄一個樣本。

Prometheus Client 函式庫對資料一致性的要求

Prometheus Client 函式庫對資料一致性的要求高。比方 Counter,如果在多執行緒的環境下,有兩個執行緒同時執行 Inc() 的情況下,我們得保證最後的值是增加 2。
一致性的要求不只體現在寫資料時,也體現在讀資料時。比方 Histogram,Observe(1) 發生時,le="1"le="2" 的值都要增加。不能在 le="1" 增加、但 le="2" 未增加時,就把 le="1"le="2" 的值讀出來。

資料一致性是由 Collector 實作負責保證的。比方 Counter 就是使用 atomic 函式庫來處理讀寫。Summary 則是使用 RWMutex 和 hot-cold buffer 來維持讀寫的效能,免得若是同時有很多 http request 進來,一直鎖著 RMutex ,導致寫入和計算百分位數的效能下降。

Push Gateway 的使用

PushGateway 是一個做為指標暫存的服務。當 Prometheus 拉取資料的時間間隔太長,或是標的的生命週期太短,來不及拉,就可以讓標的把指標資料推給 PushGateway 暫存。之後 Prometheus 再定時從 PushGateway 拉取資料。
PushGateway 和 Prometheus 是兩支不同程式,預設分別佔用 :9090 和 :9091。

使用方式

PushGateway 的使用方式很簡單,只要把指標資料推送到 /metrics/job/<job> 端點即可。其中 <job> 是一個標識符,用來區分不同的標的,需由推送者自行報告。之所以需要這個標識符,是因為 Prometheus 從 PushGateway 拉取資料時,會拉到所有不同來源推到 PushGateway 的指標,並以為它們來自同一標的。為了區分這些來源,就需要這個標識符。

HTTP Methods

推送指標到 http 的方式有 PUT 和 POST 兩種。
用 PUT 推送會把所有同 job 的指標資料覆蓋,就好像 job 被重新啟動一樣。這樣做的好處是可以避免指標資料的累積,但是也可能會造成資料遺失。
反之用 POST 推送會把指標資料加到原本的資料上,這樣做的好處是可以避免資料遺失。

指標資料格式

推送的指標資料格式和 Prometheus 拉資料的 http response 一樣,只是多了一個 job 標籤。
另一個一樣的地方是,prometheus client 函式庫提供的指標族,也可以推送指標。所以我們其實不需要知道推送的指標資料格式,只要用 prometheus client 函式庫提供推送 Registry 的介面就夠了。


上一篇
Prometheus - 寫入時間序列資料
下一篇
Prometheus - Service Discovery 和取樣時間戳
系列文
時間序列資料庫探討 - Prometheus30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言