Prometheus監控指標查詢性能調優

来源:https://www.cnblogs.com/88223100/archive/2023/08/14/Prometheus-monitoring-metrics-query-performance-tuning.html
-Advertisement-
Play Games

一、背景 在《SRE: Google運維解密》一書中作者指出,監控系統需要能夠有效的支持白盒監控和黑盒監控。黑盒監控只在某個問題目前正在發生,並且造成了某個現象時才會發出緊急警報。“白盒監控則大量依賴對系統內部信息的檢測,如系統日誌、抓取提供指標信息的 HTTP 節點等。白盒監控系統因此可以檢測到即 ...


一、背景

在《SRE: Google運維解密》一書中作者指出,監控系統需要能夠有效的支持白盒監控和黑盒監控。黑盒監控只在某個問題目前正在發生,並且造成了某個現象時才會發出緊急警報。“白盒監控則大量依賴對系統內部信息的檢測,如系統日誌、抓取提供指標信息的 HTTP 節點等。白盒監控系統因此可以檢測到即將發生的問題及那些重試所掩蓋的問題等”。為了完善系統的白盒監控,會員團隊基於 Prometheus + Grafana 開源組件構建了監控告警平臺。最近一段時間在查詢監控指標時遇到了性能瓶頸,表現為一些監控頁面的圖表載入特別慢,查詢近7天的監控數據就會失敗,極大的降低了開發人員的工作效率。

 

二、排查

1.初步排查

 

選取其中一個載入失敗的監控頁面,查詢近7天的監控數據,通過瀏覽器的開發者工具觀察到的指標數據查詢介面響應耗時如下圖所示:

圖片

 

分析指標數據查詢介面和監控圖表的對應關係後發現,監控圖表載入失敗是查詢介面超時所導致的。使用超時的指標查詢語句直接查詢 Prometheus,即便將採樣步長調高到40分鐘,查詢響應耗時依然有48秒之多。說明查詢的主要耗時都用在 Prometheus 的查詢處理上。

 

2.Prometheus查詢處理流程分析

想要繼續弄清楚 Prometheus 的查詢處理為什麼需要耗時這麼久,我們需要簡單瞭解一下 Prometheus 的查詢處理流程。Prometheus 使用了一個基於標簽(label)、值和時間戳的簡單數據模型,這些標簽和樣本一起構成了數據序列(series),每個樣本都是由時間戳和值組成。

 

圖片

 

Prometheus 將這些數據存儲在其內部的時間序列資料庫中(Prometheus 也支持外部存儲系統)。Prometheus 的資料庫被劃分為基本的存儲單元,稱為 block,其中包含一定時間範圍(預設2小時)的數據。block 的結構如下圖所示:

 

圖片

 

 

block 中最重要的兩個組成部分是 chunks 和 index。chunks 中保存的是特定序列在一定時間範圍內的採樣集合,一個 chunk 只包含一個序列的數據。index 中保存的是 Prometheus 訪問數據使用的索引信息。在 index 中保存著兩種類的索引:postings index 和 series index。

 

  • postings index:保存著標簽與包含該標簽的序列之間的對應關係。例如,標簽 __name__ ="logback_events_total" 可以被包含在兩個序列中,logback_events_total {job="app1", level="error"}和 logback_events_total {job="app2", level="error"}。

     

  • series index:保存著序列和 chunk 之間的對應關係。例如,序列 {__name__=”logback_events_total”, job=”app1”, level="error"} 可能保存在00001和00002兩個 chunk 里。

 

block 中還包含了一個 meta.json 文件(保存 block 的元數據信息)和 一個 tombstones 文件(保存已經刪除的序列以及關於它們的信息)。

 

Prometheus 的查詢處理通常包含以下五個基本步驟:

 

  • 通過查詢的時間範圍確定對應的 block。

  • 通過 postings index 確定與標簽匹配的序列。

  • 通過 series index 確定這些序列對應的 chunk。

  • 從這些 chunk 中檢索樣本數據。

  • 如果查詢中包含操作符、聚合操作或內置函數,還需要基於樣本數據進行二次計算。

 

3.詳細排查

 

瞭解了 Prometheus 的查詢處理流程後,我們可以得出以下結論:

 

1)查詢的時間範圍越大則耗時也就會越多,因為查詢時間範圍越大則涉及的 block 也會越多。

 

2)標簽的值越多則查詢耗時也就會越多,因為標簽每增加一個值就會生成一個新的序列。

 

3)查詢中使用了操作符、聚合操作或內置函數也會增加耗時,因為需要基於樣本數據進行二次計算。

 

為了後面描述方便,我們先引入一個定義:基數(cardinality)。基數的基本定義是指一個給定集合中的元素的數量。以logback_events_total 這個指標為例,我們來理解下Prometheus 中標簽基數和指標基數。

 

圖片

 

 

logback_events_total 指標有兩個標簽,其中標簽 job 有兩個值,那麼它的基數為2,同理 level 標簽的基數為5,logback_events_total 指標的基數為10。指標基數越高查詢耗時也就會越多。

 

理解了基數的定義後,我們選取一個查詢超時的監控指標來進行基數分析。先看下這個指標的一條標簽數據:

http_server_requests_seconds_count{
    application="app1", 
    cluster="cluster1", 
    exception="xxxException", 
    instance="xxx", 
    job="app1", 
    method="GET", 
    returnCode="A0000", 
    status="200", 
    uri="/xxx"
}

 

執行如下 PromQL(Prometheus自定義的數據查詢語言) 來查詢該指標每個標簽的基數(用實際標簽名替換下麵語句中的 label_name):

 

count(count by (label_name) (http_server_requests_seconds_count))

 

該指標的標簽基數彙總如下:

 

圖片

 

 

可以看到,instance 和uri 這兩個標簽的基數都很高。執行如下 PromQL 查詢該指標的基數,發現該指標的基數達到了147610。

 

count({__name__="http_server_requests_seconds_count"})

 

用同樣的方式分析了下其他問題指標,指標基數同樣達到了10萬以上。作為對比,我們抽樣分析了幾個載入比較快的指標,指標基數大都在1萬以下。因此可以確認,查詢耗時高主要是指標基數過高引起的。實際監控圖表配置的查詢語句中還使用了一些聚合操作(例如 sum)和內置函數(例如 rate),也在一定程度上增加了查詢耗時。

 

三、優化

 

Prometheus 提供了一種叫做記錄規則(Recording Rule)的方式來優化我們的查詢語句,記錄規則的基本思想是:預先計算經常要用或計算開銷較大的表達式,並將其結果保存為一組新的時間序列。以上面提到的 http_server_requests_seconds_count 這個指標為例,優化前的一個監控圖表的查詢語句如下:

 

sum(rate(http_server_requests_seconds_count{application="$application", cluster=~"$cluster", uri!~"/actuator/.*|/\\*.*|root|/|/health/check"}[1m])) by (uri)

 

從查詢語句可以看出,該監控圖表依賴於 application、cluster 和 uri 這三個標簽的聚合數據,因此可以創建如下的記錄規則(記錄規則的詳細創建方式可以參考 Prometheus 官方文檔):

 

record: http_server_requests_seconds_count:rate:1m:acuexpr: sum(rate(http_server_requests_seconds_count{uri !~ "/actuator/.*|/\\*.*|root|/|/health/check"}[1m])) by (application,cluster,uri)

 

記錄規則創建後預設只包含記錄規則創建時間之後的數據,並不包含創建之前的歷史數據。Prometheus從 v2.27 版本開始支持通過命令行指令來手工回溯歷史數據(對於 Prometheus v2.38及以下版本,需要在實例啟動時開啟--storage.tsdb.allow-overlapping-blocks 參數),通過 promtool tsdb create-blocks-from rules --help 可以瞭解該指令的使用,這裡給出了一個該指令的樣例:


promtool tsdb create-blocks-from rules \
--start 1680348042 \
--end 1682421642 \
--url http://mypromserver.com:9090 \
rules.yaml

 

promtool tsdb create-blocks-from rules 命令的輸出是一個目錄(預設是 data/ ),其中包含了記錄規則文件中所有規則歷史數據的 block。為了讓新生成的 block 生效,必須將它們手工移動到正在運行的 Prometheus 實例數據目錄下。移動後,新產生的 block 將在下一次壓縮運行時與現有 block 合併。

 

在執行完上面的操作後通過 PromQL 查詢這個記錄規則的基數,發現指標基數下降到了4878。原來監控圖表的查詢語句可以調整為:

 

sum(http_server_requests_seconds_count:rate:1m:acu{application="$application", cluster=~"$cluster"}) by (uri)

 

對優化後的監控圖表進行測試,效果對比如下圖所示,可以看到查詢的時間範圍越長,效果提升越明顯。這主要得益於記錄規則帶來的指標基數大幅降低以及函數計算的預先處理。

 

圖片

 

 

在實際場景中,如果有多個監控圖表都用到了同一個監控指標,可以整體評估一下記錄規則應該怎麼創建。因為一個記錄規則也是一組時間序列,在滿足查詢需求的前提下儘量避免創建過多的記錄規則。

 

四、小結

 

當 Prometheus 指標基數過高時,就會出現監控圖表載入很慢甚至載入失敗。通過 Prometheus 提供的記錄規則,我們可以對查詢語句進行優化從而減少查詢耗時。除了記錄規則外,還有一些技巧可以優化查詢性能,例如增加 Prometheus 指標採集間隔,刪除不用的指標序列等。實際上,在監控指標設計階段就應該對指標基數進行評估,必要時對標簽取值進行取捨。例如,一個標簽對應 HTTP 響應碼,可以將它的取值定義為 1XX、2XX、3XX、4XX、5XX,相比詳細的響應碼可以大大降低指標基數。

 

作者丨會員技術團隊

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Prometheus-monitoring-metrics-query-performance-tuning.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • WindowsServer伺服器管理技巧:對於使用WindowsServer伺服器開發人員或者運維人員初學者來說,可能會遇到很多問題,比如:如何設置允許多用戶同時登錄伺服器?如何開啟伺服器防火牆?Windows如何配置SSH遠程登錄?等等,如果遇到了這些問題,來看看這篇文章就能解決啦! ...
  • 國產銀河麒麟系統也是生產環境上經常遇到的(官網簡介:銀河麒麟高級伺服器操作系統V10 - 國產操作系統、銀河麒麟、中標麒麟、開放麒麟、星光麒麟——麒麟軟體官方網站 (kylinos.cn)) 這版系統分為伺服器版和個人桌面版;其中伺服器版命令估計是基於紅帽體系;而桌面版命令估計是基於Ubuntu,很 ...
  • 設計字元設備 文件系統調用系統IO的內核處理過程 inode索引節點是文件系統中的一種數據結構,用於存儲文件的元數據信息,包括文件的大小、訪問許可權、創建時間、修改時間等。每個文件在文件系統中都對應著一個唯一的inode節點,通過inode節點可以查找到文件的實際數據塊的位置。inode節點通常存儲在 ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230813220820722-927556191.png) # 1. 邏輯架構 ## 1.1. 大多數基於網路的客戶端/伺服器工具或伺服器都有類似的服務 ### 1.1.1. ...
  • ![file](https://img2023.cnblogs.com/other/3195851/202308/3195851-20230814171638731-1116543252.jpg) 作者 | 郭煒 策劃 | 凌敏 ## 前言 下麵是一段利用 Co-Pilot 輔助開發的小視頻,這是 ...
  • srandmember key [count]count: 為可選的參數 作用: 如果 count 為正數,且小於集合基數,那麼命令返回一個包含 count 個元素的數組,數組中的元素各不相同。如果 count 大於等於集合基數,那麼返回整個集合。如果 count 為負數,那麼命令返回一個數組,數組 ...
  • 本篇技術博文將深入探討 Redis 持久化機制的原理、配置和使用方式。我們將介紹兩種常用的持久化方式:RDB 持久化和 AOF 持久化。您將瞭解到它們的工作原理、優缺點以及如何根據需求選擇合適的持久化方式。 通過深入學習 Redis 持久化及集群架構,您將能夠構建穩定、可靠並具備高可用性的 Red... ...
  • ## 1、背景 公司內部看到一則問題 > 1、kill -9 mysqld_safe 進程 > 2、systemd 檢測到 mysqld_safe 進程不存在後,重新拉起 mysqld_safe 進程 > 3、mysqld_safe 進程啟動後,發現 mysqld 進程也被重啟 期望:啟、停 mys ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...