當前位置: 妍妍網 > 碼農

30個Pull請求後,Prometheus記憶體使用量銳減一半

2024-02-04碼農

Grafana Labs 傑出工程師 Bryan Boreham 在 KubeCon 上詳細介紹了他如何減少 Prometheus 的記憶體使用量。

Prometheus 記憶體消耗是觀測可觀察性可能導致系統崩潰的方式之一。

Grafana Labs 的傑出工程師Bryan Boreham在 KubeCon+CloudNativeCon 的演講中,詳細介紹了他如何嘗試各種方法,最終減少Prometheus的記憶體使用量的經歷。他演講的標題是「Prometheus 如何將記憶體使用減半」,講述了他對 Prometheus 的研究,特別是標簽的記憶體消耗,揭示了減少記憶體消耗的方法。

根據Prometheus 文件,標簽用於 區分 正在測量的事物的特征:

  • api_http_requests_total – 區分請求型別: **operation=create|update|delete**

  • api_request_duration_seconds – 區分請求階段: stage=extract|transform|load

  • Boreham 的工作也本著開源精神,展示了貢獻如何能夠帶來實質成果。在兩年時間內,向監控系統計畫提出了 30 個拉取(Pull)請求,修改了2500多行程式碼,Boreham 的工作幫助最新版本的 Prometheus 記憶體使用量銳減至之前版本的一半。

    「這是一條漫長的道路,但最終(結果)令人非常滿意。」 Boreham 在KubeCon+CloudNativeCon 之後告訴 The New Stack,「數十萬台 Prometheus 伺服器在執行,透過降低記憶體需求,我們降低了執行它們的成本及其碳足跡。」

    Go 的記憶體分析器

    Boreham 在演講中解釋道,Go程式語言在執行時內建一個效能分析器,可以提供 Prometheus 記憶體以及 CPU 使用情況的記憶體消耗分析。效能分析器提供視覺化火焰圖(flame graph,譯者註:火焰圖展示了程式在執行過程中不同函式的呼叫關系和耗時情況,通常使用顏色來表示函式的執行時間,顏色越深則說明函式執行時間越長)。圖中長方形的寬度是正在使用的記憶體量的比例。Boreham 表示,上圖頂部顯示 100%,總共 6.7 GB 的記憶體消耗。

    圖表中出現了所謂的 鋸齒效應(sawtooth effect) 。Boreham 告訴 The New Stack,隨著時間推移垃圾不斷積累,然後被收集,因此記憶體急劇下降,然後垃圾重新積累,這就是鋸齒效應。

    「Go 記憶體分析器報告上次垃圾回收時的記憶體使用情況,因此,您在這張圖片中永遠不會看到垃圾。很多人認為,‘哦,這可能主要是垃圾,我不需要考慮它’。「Boreham說道,「但是當你檢視 Go 的配置檔時,這絕不是垃圾。這是鋸齒底部,是不能丟棄的內容。」

    「減少記憶體消耗的過程首先要問,‘好吧,是什麽讓它變得這麽大?’。但總體而言,獲勝者是大約兩年前的情況,Prometheus 內部幾乎三分之一的記憶體都被標簽占用了(圖中為 31%)。」

    Prometheus 標簽的問題

    Boreham 解釋說,Prometheus 中的每個系列(Series)都由這個名稱/值對集唯一標識。如果你有另一個相關的系列,唯一的區別在於方法,實際上,你會得到一套全新的字串。「所以,你看了會說,好吧,這很愚蠢,我只有一份字串。但事情並沒有那麽簡單。」

    上圖展示了其中的數據結構。指向所有標簽的切片檔頭為24字節,每個字串都有一個16字節的字串檔頭。「它是一個指向內容和長度的指標, 如果你把它們全部加起來,就會發現數據結構中的所有這些指標的大小都比字串本身大得多。」

    使用Prometheus PR 10991,Boreham 將所有字串放入一個字串中,並用長度對它們進行編碼:

    「花一年的時間更改了2500行程式碼,因為有大量程式碼只是假設它自己知道數據結構是什麽樣的。」

    在 Prometheus 2.74.2 中,雖然之前的版本會在17 GB記憶體消耗時崩潰,但 Boreham 執行2.47.2,記憶體消耗為13.1GB,沒有發生任何事故:

    雖然2.47.2中添加了樣本處理和原生直方圖功能,但「它們並沒有真正耗盡所有記憶體,」Boreham 說,雖然記憶體消耗顯著減少,但尚未完全達到50%的水平。

    Boreham 隨後發現並修復了 2.39 中的一個錯誤:事務隔離環,該錯誤「過去在某些條件下會變得巨大」,Boreham 說。「但我算了一下,記憶體消耗仍然沒有完全減少一半」:

    該錯誤修復將記憶體消耗減少至 10 GB:

    Boreham 繼續研究 Go 分析器,以瞄準記憶體消耗的罪魁禍首。

    選擇最大的數位,然後研究它,如果可以找到其中的一些低效之處,然後再做一遍。原來第二大數位現在變成了最大數位,一開始並沒有那麽大的數位現在已經是很大的數位了。所以這是一次很好的自我強化過程。

    這是 2.47 加上上圖中的所有 PR,總共 8.6 GB 記憶體消耗,幾乎達到了 50% 的減少標記:

    正如 Boreham 的解釋,Go 執行時中有一個參數名為 GoGC,預設值為 100。鋸齒大小增長到鋸齒底部大小的 100%,即 7 GB。對於那些擁有 100 GB Prometheus 的人來說,它增長了 50 GB,但出於維護目的,你不需要 50 GB 的垃圾來執行有效的堆,你可以調整這個數位——這是一個可設定的環境變量,它會增長到你設定的百分比,超過其最小值,並且垃圾收集速度會加快一些。

    Prometheus 此後一直在 8 GB 記憶體下執行——記憶體消耗已達到 50%。Boreham已經達到了他的目標:

    Prometheus 使用者必然傾心更低的記憶體消耗,而大多數人怎麽實作記憶體低消耗可能不太感興趣。

    但對於那些喜歡回饋開源社群的人來說,Boreham 的艱辛表明,只要付出大量的工作和耐心,就可以提出能夠產生實際影響的拉取請求 (PR)。雖然Boreham的工作在事後看來可能很簡單,但顯然並非如此——數學和科學研究中經常出現這種情況。Prometheus 以及一般的開源計畫為使用者和那些對計算感興趣的人提供了做出貢獻的機會。

    Boreham告訴 The New Stack:「這確實是一種為愛發電的工作,讓電腦程式變得更小、更快對我來說是一種癡迷愛好,所以能夠在如此受歡迎和廣泛使用的計畫中被采用真是太好了。而且,在 Grafana Labs,‘開源深植於我們的DNA中’。」

    編譯丨公眾號:DevOps雲學堂(ID:idevopsvip)

    來源丨thenewstack.io/30-pull-requests-later-prometheus-memory-use-is-cut-in-half/

    dbaplus社群歡迎廣大技術人員投稿,投稿信箱: [email protected]