Skip to content

簡單理解 Summary 和 Histogram 指標

原文: prometheus的summary和histogram指標的簡單理解

Histogram 指標

histogram 是直方圖,在 Prometheus 系統中的查詢語言中,有三種型式的指標產生:

  • 對每個採樣點進行統計,打到各個數值桶中(bucket)
  • 對每個採樣點值累計和(sum)
  • 對採樣點的次數累計和(count)

舉例來說一個度量指標名稱: [basename]的 histogram, 會產生下面三類的度量指標名稱:

  • [basename]_bucket{le="上邊界"}, 這個值爲小於等於上邊界的所有採樣點數量
  • [basename]_sum
  • [basename]_count

Histogram 範例

假設我們想監控某個應用在一段時間內的某一個 API 服務被呼叫時的響應時間,最後監控到的樣本的響應時間範圍為 0s ~ 10s。現在我們將樣本的值域劃分為不同的區間,即不同的 bucket,下列的範例把 bucket 設成 [1,5,10]。

指標名稱: http_request_duration_seconds

如上表,設置 bucket=[1,5,10],當實際採樣數據如是"樣本"欄所示, "樣本數(count)"表示採樣點落在該 bucket 中的數量:

  • 落在 [-,1] 的樣點數爲 2
  • 落在 [1,5] 的樣點數爲 3
  • 落在 [5,10] 的樣點數爲 1

"累積樣本數(count)"是得到的最終結果(histogram 的最終結果 bucket 計數是向下累積的):

指標 
http_request_duration_seconds_bucket{le=“1”} 2
http_request_duration_seconds_bucket{le=“5”} 3
http_request_duration_seconds_bucket{le=“10”} 6
http_request_duration_seconds_bucket{le="+Inf"} 6
http_request_duration_seconds_count 6
http_request_duration_seconds_sum 18.8378745

Prometheus 並不會為 Histogram  保存採樣點的值,每個 bucket 只有記錄樣本數的 counter(float64),也就是 Histogram 存儲的是區間的樣本數統計值,因此在客戶端進行 Histogram 資料的收集時的性能開銷相比於 CounterGauge 而言沒有明顯改變,適合高併發的數據收集。

Summary 指標

因爲 Histogram 在客戶端就是進行了簡單的分桶和分桶計數,在 prometheus 服務端基於這樣的數據做百分位估算時,所以的確不是很準確,而 Summary 就是解決百分位準確的問題而來的。

Summary 直接存儲了 quantile 數據,而不是根據統計區間計算出來的。Prometheus 的分位數稱爲 quantile,其實叫 percentile 更準確。百分位數是指小於某個特定數值的採樣點達到一定的百分比。

Summary 是採樣點分位圖統計。 有三種型式的指標產生:

  • 在客戶端對於一段時間內的每個採樣點進行統計,並形成分位圖。(如:常態分佈一樣,統計低於60分不及格的同學比例,統計低於80分的同學比例,統計低於95分的同學比例)
  • 統計班上所有同學的總成績(sum)
  • 統計班上同學的考試總人數(count)

舉例來說一個度量指標名稱: [basename]的 summary, 會產生下面三類的度量指標名稱:

  • [basename]{quantile="0.5"}, [basename]{quantile="0.9"}, [basename]{quantile="0.99"}
  • [basename]_sum
  • [basename]_count

Summary 範例

假設我們想監控 prometheus 服務器進行 was_fsync 操作所花費的時間:

# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216

從上面的樣本中可以得知當前 Prometheus Server 進行 wal_fsync 操作的總次數爲 216 次,耗時 2.888716127000002 秒 。

其中 中位數 P50 (quantile=0.5) 的耗時都小於 0.012352463 秒,9分位數 P90 (quantile=0.9) 的耗時都小於 0.014458005 秒,P99(quantile=0.99) 的耗時都小於等於 0.017316173 秒。

分位數計算的選擇

要計算分位數有二種選擇:

  1. 使用 Histogram 指標搭配 histogramquantile 函數
  2. 直接使用 Summary 指標

至於使用那一種方式比較好呢? 底下列出一些考量點:

  • Summary 結構有頻繁的全局鎖操作,對高併發程序性能存在一定影響。Histogram 僅僅是給每個桶做一個原子變量的計數就可以了,而 Summary 要每次執行算法計算出最新的X分位 value 是多少,算法需要併發保護。會佔用客戶端的cpu和內存。

  • 不能對 Summary 產生的 quantile 值進行 aggregation 運算(例如 sum, avg 等)。例如有兩個實例同時運行,都對外提供服務,分別統計各自的響應時間。最後分別計算出的0.5-quantile 的值爲 60 和 80,這時如果簡單的求平均 (60+80)/2,認爲是總體的 0.5-quantile 值,那麼就錯了。

  • Summary 的百分位是提前在客戶端裏指定的,在服務端觀測指標數據時不能獲取未指定的分位數。而 Histogram 則可以通過 promql 隨便指定,雖然計算的不如Summary 準確,但帶來了靈活性。

  • Histogram 不能得到精確的分位數,如果設置的 bucket 不合理的話,誤差會非常大。會消耗服務端的計算資源。

建議

  • 如果需要聚合(aggregate),選擇 Histogram。
  • 如果比較清楚要觀測的指標的範圍和分佈情況,選擇 Histogram。如果需要精確的分位數選擇 Summary。