[Mimir] 智慧之泉 - Mimir 啟迪監控新境界
Background
Grafana Mimir 的前身可追溯到 Cortex,早在 2016 年,當時在 Weaveworks 工作的 Tom Wilkie 與 Prometheus 的共同創始人 Julius Volz 就開始研發 Cortex,旨在構建一個可與 Prometheus 相容、具備水平擴展能力的監控解決方案,以解決 Prometheus 單機性能限制的問題。
但由於後來 Cortex 的技術債太過於嚴重,並且由於開源條款的限制,讓 Grafana Labs 決定基於 Cortex 的程式碼重構,在 2022 年正式發布了 Grafana Mimir。
Mimir 指的是北歐神話中的智慧巨人,由巨人之祖 Ymir 所生,是智慧之泉的主人,擁有無比的智慧與知識,傳說中,奧丁甚至為了飲用泉水獲得智慧,犧牲了自己的右眼。 Grafana Labs 選擇使用 Mimir 作為這個時序資料庫的名稱,正是希望借用這位北歐智者象徵的深厚知識與記憶,表達其系統能夠儲存、管理並從海量監控數據中萃取出關鍵洞察的能力。
Introduction
Grafana Mimir is an open source, horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.
Grafana Mimir 是一個高效並可水平擴展的時序資料庫,專為 Prometheus 設計,用來處理海量時序數據的儲存與查詢。
Mimir 的核心功能如下 :
- 可擴展性 : Mimir 可以水平擴展,支援多個實例,並且可以自動平衡數據
- 單一資料源 : Mimir 可以支援多個 Prometheus 實例,並且可以將數據合併到單一資料源
- 長期存儲 : Mimir 可以存儲在物件存儲中節省成本
Mimir 可以很好的與 Prometheus 配合使用,Prometheus 可以扮演蒐集數據的角色,使用 remote_write 將數據寫入 Mimir,而 Mimir 則可以提供長期存儲、高效查詢的功能。
Components
Grafana 系列的產品 (Loki、Tempo) 在架構上其實都很相似,都是由一些基本的元件組成,Mimir 也不例外,以下是 Mimir 的一些基本元件 :
Read Path & Write Path Flow
Compactor
Mimir 的 Compactor 是一個 stateless 的服務,主要負責以下幾個功能 :
- block compaction : 將同一租戶在相同時間範圍內由多個 Ingester 上傳的 TSDB 區塊合併成一個經過優化的大區塊。這個合併過程會同時對數據進行 deduplication,減少儲存索引的大小
- block deletion : 刪除過期的 block,控制資料膨脹
- index compaction : 每個租戶都會有自己的 bucket index,這個 index 會儲存每個租戶的 block 跟 deletion mark,可以幫助 Querier、Ruler、Store Gateway 快速找到需要的 block
Compactor 的 compaction 操作是在每個租戶的層級上執行的,間隔為一個可配置的時間,主要分為兩個階段 :
-
Vertical compaction :
對於同一時間範圍內 (預設為 2 小時) 的所有區塊進行合併。 垂直合併會將這些來自多個 Ingester 的區塊合併成一個單一區塊,並進行重複數據消除,將原本分散的多個區塊壓縮為一個區塊。
-
Horizontal compaction :
當垂直合併完成後,對於相鄰的時間範圍內的區塊進行再次合併,以形成更大的區塊。 水平合併可以大幅度減少 store-gateway 在記憶體中需要保存的 index 與 index-header 的大小,提升查詢性能。
Mimir 使用的 compaction algorithm 稱為 split and merge,主要分成 split 跟 merge 兩個階段,預設不使用 split,只使用 merge。
-
Split stage
在資料寫入時,由於出於高可用性考量,單一時間序列可能會被複製到多個 Ingester 上,這也就導致同一時間範圍內會產生多個 TSDB 區塊,而 split 階段的設計就是為了將這些數據拆分成更小、且更容易平行處理的區塊。
首先會依據
-compactor.split-groups
來自同一時間範圍內的所有源區塊劃分為 N 個組,接著 Compactor 會對每個組進行拆分, 這個拆分的過程是根據參數-compactor.split-and-merge-shards
來設定 M (分片數) 的,也就是說,每個組會被拆分成 M 個不同的分片。 最終在此階段結束後,總共會 產生 N X M 個拆分後的中間區塊。每個這類中間區塊在其meta.json
檔案中都會記錄所屬的分片資訊。 -
Merge stage
針對每一個分片,Compactor 將來自不同組的拆分區塊進行合併,這個合併過程會同時完成重複數據消除,最終產生 M 個合併後的區塊。
Distributor
Distributor 一樣是一個 stateless 的服務,主要負責以下幾個功能 :
- 負責接收由 Prometheus 或是 Grafana Alloy 傳輸的資料,並進行驗證
- 限制每個租戶的請求速率
- 將資料分發給多個 Ingester,並且可以自動平衡數據
Ingester
Ingester 是一個 stateful 的服務,主要負責將資料寫入 Object Storage,以及在讀取資料時返回記憶體中的數據。
其功能與實作與 Loki 中的 Ingester 類似,如果 Ingester 發生故障,同樣可以使用 WAL 來保證數據不會丟失,比較特別的是使用了 WBL (Write Behind Log) 來處理亂序的資料寫入。
Querier
Querier 是一個 stateless 的服務,主要用於執行 PromQL 查詢,並且可以將查詢結果返回給用戶。 它會連接到 Store Gateway 和 Ingester 來獲取數據,並將結果聚合後返回給 Frontend。
Query Frontend
Query Frontend 是一個 stateless 的服務,提供了與 Querier 相同的 API,並透過內部的查詢服務以及快取等等的方式來提升查詢效率。
與 Loki 中的 Query Frontend 類似。
Store Gateway
Store-gateway 是一個 stateful 的元件,主要負責從長期儲存 (例如 S3、GCS)中查詢 TSDB 區塊。 在讀取路徑中,不論是用戶端查詢還是告警規則,Querier 與 Ruler 都會通過 store-gateway 來獲取數據。
為了在查詢時能夠找到正確的區塊,store-gateway 必須持續獲得長期儲存桶的索引,包含了每個租戶的所有區塊及其刪除標記等信息。
當 store-gateway 啟動時,會對每個租戶下載一次 bucket index,並根據此信息了解該租戶的所有區塊以及刪除標記。
對於每個發現的區塊,store-gateway 會下載該區塊的 index header 到本地硬碟,
在這個同步過程中,store-gateway 的 /ready
就緒探針會回報 not-ready 狀態,直到所有必需的區塊 index header 被加載完成。
Reference
- Grafana Mimir
- Grafana Mimir Docs
- 可觀測性宇宙的第二十八天 - Grafana Mimir 介紹 - 監控指標的應許之地
- Mimir - 收羅萬象的智者
- Observability strategy at Adobe, with OpenTelemetry, Grafana, Mimir, and Tempo
- Announcing Grafana Mimir, the most scalable open source TSDB in the world
- Grafana Mimir: Maintainers tell all
- 一文带你了解 Grafana 最新开源项目 Mimir 的前世今生
- 密米爾-維基百科