雲原生報警背景現狀
在雲原生的生态下,kubernetes 已經被越來越多地應用到公司實際生産環境中。在這樣的生态環境下系統監控、業務監控和資料庫監控名額都需要在第一時間擷取到,目前用的最多的也是
prometheus
、
exporter
、
grafana
、
alertmanager
這幾個軟體組建起來建構自己的監控系統。以上這幾款軟體組建監控系統比較容易。可是在告警這一環節,隻能依靠終端
vim
來編輯規則檔案。今天給大家推薦一款可以可視化操作的告警軟體,這個軟體是将
prometheus
和
alertmanager
進行了結合可以把資料分散存儲起來,通過可視化的操作添加 prometheus 告警規則,這個軟體就是 grafana 公司開發的
mimir
。
Mimir 是做什麼的
Mimir 為 prometheus 提供水準可擴充、高度可用、多租戶的長期存儲。它的工作架構如下圖展示:
Mimir 架構
- 存儲 Prometheus metrics 使用 Prometheus 從應用程式中提取名額,并将這些名額遠端寫入 Mimir,或者使用 Grafana Agent、PrometheusAgent 或其他 Prometheus 遠端寫入相容軟體直接發送資料。
- 擴充性強 Mimir 群集不需要手動進行切分、複制或重新平衡。要增加容量,隻需向叢集添加新執行個體。
- 在 grafana 中可視化 Mimir 允許使用者運作查詢,通過記錄規則建立新資料,并利用租戶聯合在多個租戶之間設定警報規則。所有這一切都可以與 Grafana 儀表盤聯系在一起。
Mimir 元件都有哪些,它們是做什麼的?
類型 | 組建名稱 |
可選 | alertmanager,ruler,overrides-exporter,query-scheduler| |
必選 | compactor,distributor,ingester,querier,query-frontend,store-gateway |
以上列舉出了 Mimir 的一些元件,下面介紹一下它們分别是做什麼的
Compactor(資料壓縮器,無狀态應用)
compactor 通過組合塊提高查詢性能并減少長期存儲使用。負責以下工作:
- 将給定租戶的多個資料塊壓縮為單個優化的較大資料塊。這可以消除資料塊并減小索引的大小,進而降低存儲成本。查詢更少的塊更快,是以也提高了查詢速度。
- 保持每租戶的資料存儲桶索引更新,存儲桶索引被
、queriers
和 store-gateway
使用,用來發現資料中新增加的資料塊和删除資料塊rulers
- 删除那些不再在可配置保留期内的資料塊。
工作原理
按租戶以固定、可配置時間間隔進行資料塊壓縮。垂直壓縮将接收器在同一時間範圍(預設情況下為 2 小時内)上傳的租戶的所有塊合并到單個塊中。它還對最初由于複制而寫入 N 個塊的樣本執行重複資料消除。垂直壓縮減少了單個時間範圍内的塊數。垂直壓縮後觸發水準壓縮。它将幾個具有相鄰範圍周期的塊壓縮為一個較大的塊。水準壓縮後,關聯塊塊的總大小不變。水準壓縮可以顯着減小存儲網關儲存在記憶體中的索引和索引頭的大小。如下圖
縮放
可以針對具有大型租戶的叢集調整壓縮。配置指定了壓縮程式在按租戶壓縮時如何運作的垂直和水準縮放。垂直縮放:
-compactor.compaction-concurrency
選項配置了單個壓縮執行個體中運作的最大并發壓縮數。每次壓縮使用一個 CPU 核心。水準縮放:預設情況下,租戶區塊可以使用任何 Mimir 進行資料壓縮。當通過将
-compactor.compactor-tenant-shard-size
(或其相應的 YAML 配置選項)設定為大于 0 且小于可用 compactors 執行個體數量的值來啟用壓縮随機分片時,僅指定 compactor 的數量才有資格為給定的租戶壓縮資料塊。
壓縮算法
Mimir 使用了一種稱為拆分和合并的複雜壓縮算法。通過設計,拆分和合并算法克服了時間序列資料庫(TSDB)索引的局限性,并且它避免了壓縮塊在任何壓縮階段對一個非常大的租戶無限期增長的情況。這種壓縮政策是一個兩階段的過程:拆分和合并,預設配置禁用拆分階段。
拆分階段第一級是壓縮。例如:2 小時内 compactor 将所有源資料庫分割成 N 個組(通過
-compactor.split-groups
設定)。對待每一個組 compactor 壓縮資料塊而不是生成單個的結果塊,輸出 M 個分割塊(通過
-compactor.split-and-merge-shards
設定)。每個分割塊隻包含了屬于 M 碎片中給定碎片的序列子集。在分割階段結束時,compactor 會參考塊檔案(meta.json)中各自碎片資訊的引用來産生
N*M
個資料塊。Compactor 合并每個碎片的分割塊,将壓縮給定碎片的所有 N 個分割塊。合并将塊數從
N*M
減少到
M
。對于給定的壓縮時間範圍,每個 M 碎片都将有一個壓縮塊。如下圖所展示的說明
壓縮共享
Compactor 将來自單租戶或者多租戶的壓縮作業進行碎片化處理。單個租戶的壓縮可以由多個壓縮器執行個體分割和處理。無論壓縮器執行個體的數量何時增加或減少,租戶和任務崗位都會在可用壓縮器執行個體中重新配置設定,而無需任何手動幹預。壓縮器使用哈希環進行分片。在啟動時,壓縮器生成随機令牌并将自身注冊到壓縮器哈希環。在運作時,它每隔一段時間(通過
-compactor.compaction-interval-compactor.compaction-interval
設定)定期掃描存儲桶,以發現每個租戶的存儲和壓縮塊中的租戶清單,這些租戶的哈希與哈希環中配置設定給執行個體本身的令牌範圍相比對。
阻止删除
成功壓縮後,将從存儲中删除原始塊。塊删除不是立即進行的;它遵循兩步過程:
- 原始塊标記為删除;這是軟删除
- 一旦一個塊被标記為删除的時間超過了可配置壓實機的時間。删除延遲,從存儲器中删除塊;這是一個硬删除。
壓縮器負責标記塊和硬删除。軟删除基于存儲在 bucket 中塊位置中的一個小檔案(deletion-mark.json)。成功壓縮後,将從存儲中删除原始塊。塊删除不是立即進行的;它遵循兩步過程:1. 原始塊标記為删除;這是軟删除 2. 一旦一個塊被标記為删除的時間超過了可配置壓實機的時間。删除延遲,從存儲器中删除塊;這是一個硬删除。
壓實機負責标記塊和硬删除。軟删除基于存儲在 bucket 中塊位置中的一個小檔案。軟删除機制為
queriers
,
rulers
和
store-gateways
提供了時間,以便在删除原始塊之前發現新的壓縮塊。如果這些原始塊被立即硬删除,則涉及壓縮塊的某些查詢可能會暫時失敗或傳回部分結果。
distributor(資料分發器)
分發伺服器是一個無狀态元件,從 Prometheus 或 Grafana 代理接收時間序列資料。分發伺服器驗證資料的正确性,并確定資料在給定租戶的配置限制内。然後,分發伺服器将資料分為多個批次,并将其并行發送給多個接收程式,在接收程式之間切分序列,并通過配置的複制因子複制每個序列。預設情況下,配置的複制因子為 3。
工作原理
驗證
分發伺服器在将資料寫入 ingester 之前驗證其接收的資料。因為單個請求可以包含有效和無效的度量、樣本、中繼資料和樣本,是以分發伺服器隻将有效資料傳遞給 ingester。分發伺服器在其對接收程式的請求中不包含無效資料。如果請求包含無效資料,分發伺服器将傳回 400 HTTP 狀态代碼,詳細資訊将顯示在響應正文中。關于第一個無效資料的詳細資訊無論是普羅米修斯還是格拉夫納代理通常由發送方記錄。分發器驗證包括以下檢查:
- 度量中繼資料和标簽符合普羅米修斯公開格式。
- 度量中繼資料(名稱、幫助和機關)的長度不超過通過
定義的長度validation.max-metadata-length
- 每個度量的标簽數不高于
-validation.max-label-names-per-series
- 每個度量标簽名稱不得長于
-validation.max-length-label-name
- 每個公制标簽值不長于
-validation.max-length-label-value
- 每個樣本時間戳都不晚于
-validation.create-grace-period
- 每個示例都有一個時間戳和至少一個非空标簽名稱和值對。
- 每個樣本不超過 128 個标簽。
速率限制
分發器包括适用于每個租戶的兩種不同類型的費率限制。
-
請求速率
每個租戶每秒可以跨 Grafana Mimir 叢集處理的最大請求數。
-
接受速率
每個租戶在 Grafana Mimir 叢集中每秒可接收的最大樣本數。如果超過其中任何一個速率,分發伺服器将丢棄請求并傳回 HTTP 429 響應代碼。
在内部,這些限制是使用每個分發器的本地速率限制器實作的。每個分發伺服器的本地速率限制器都配置了
limit/N
,其中 N 是正常分發伺服器副本的數量。如果分發伺服器副本的數量發生變化,分發伺服器會自動調整請求和接收速率限制。因為這些速率限制是使用每個分發伺服器的本地速率限制器實作的,是以它們要求寫入請求在分發伺服器池中均勻分布。可以通過下面的這幾個參數進行限制:
-
-distributor.request-rate-limit
-
-distributor.request-burst-size
-
-distributor.ingestion-rate-limit
-
-distributor.ingestion-burst-size
高可用跟蹤器
遠端寫發送器(如 Prometheus)可以成對配置,這意味着即使其中一個遠端寫發送機停機進行維護或由于故障而不可用,度量也會繼續被擦除并寫入 Grafana Mimir。我們将此配置稱為高可用性(HA)對。分發伺服器包括一個 HA 跟蹤器。啟用 HA 跟蹤器後,分發伺服器會對來自 Prometheus HA 對的傳入序列進行重複資料消除。這使您能夠擁有同一 Prometheus 伺服器的多個 HA 副本,将同一系列寫入 Mimir,然後在 Mimir 分發伺服器中對該系列進行重複資料消除。
切分和複制
分發伺服器在 ingester 之間切分和複制傳入序列。您可以通過
-ingester.ring.replication-factor
配置每個系列寫入的攝取器副本的數量。複制因子預設為 3。分發者使用一緻哈希和可配置的複制因子來确定哪些接收者接收給定序列。切分和複制使用 ingester 的哈希環。對于每個傳入的序列,分發伺服器使用度量名稱、标簽和租戶 ID 計算哈希。計算的哈希稱為令牌。分發伺服器在哈希環中查找令牌,以确定向哪個接收程式寫入序列。
仲裁一緻性
因為分發伺服器共享對同一哈希環的通路,是以可以向任何分發伺服器發送寫請求。您還可以在它前面設定一個無狀态負載平衡器。為了確定一緻的查詢結果,Mimir 在讀寫操作上使用了 Dynamo 風格的仲裁一緻性。分發伺服器等待 n/2+1 接收程式的成功響應,其中 n 是配置的複制因子,然後發送對 Prometheus 寫入請求的成功響應。
分發器之間的負載平衡
在分發伺服器執行個體之間随機進行負載平衡寫入請求。如果在 Kubernetes 叢集中運作 Mimir,可以将 KubernetesService 定義為分發器的入口。
ingester(資料接收器)
接收程式是一個有狀态元件,它将傳入序列寫入長期存儲的寫路徑,并傳回讀取路徑上查詢的序列樣本。
工作原理
來自分發伺服器的傳入序列不會立即寫入長期存儲,而是儲存在接收伺服器記憶體中或解除安裝到接收伺服器磁盤。最終,所有系列都會寫入磁盤,并定期(預設情況下每兩小時)上傳到長期存儲。是以,查詢器可能需要在讀取路徑上執行查詢時,從接收器和長期存儲中擷取樣本。任何調用接收器的 Mimir 元件都首先查找哈希環中注冊的接收器,以确定哪些接收器可用。每個接收器可能處于以下狀态之一:
- pending
- joining
- active
- leaving
- unhealthy
寫放大
Ingers 将最近收到的樣本存儲在記憶體中,以便執行寫放大。如果接收器立即将收到的樣本寫入長期存儲,由于長期存儲的高壓,系統将很難縮放。由于這個原因,接收器在記憶體中對樣本進行批處理和壓縮,并定期将它們上傳到長期存儲。寫反放大是 Mimir 低總體擁有成本(TCO)的主要來源。
接收失敗和資料丢失
如果接收程式程序崩潰或突然退出,則所有尚未上載到長期存儲的記憶體中序列都可能丢失。有以下方法可以緩解這種故障模式:
- Replication
- Write-ahead log (WAL)
- Write-behind log (WBL), out-of-order 啟用時
區域感覺複制
區域感覺複制可確定給定時間序列的接收副本跨不同的區域進行劃分。分區可以表示邏輯或實體故障域,例如,不同的資料中心。跨多個區域劃分副本可防止在整個區域發生停機時發生資料丢失和服務中斷。
無序切分
亂序切分可以用來減少多個租戶對彼此的影響。
無序樣本接收
預設情況下會丢棄無序樣本。如果将樣本寫入 Mimir 的系統産生無序樣本,您可以啟用此類樣本的接收。
querier(查詢器)
查詢器是一個無狀态元件,它通過在讀取路徑上擷取時間序列和标簽來評估 PromQL 表達式,使用存儲網關元件查詢長期存儲,使用接收元件查詢最近寫入的資料。
工作原理
為了在查詢時查找正确的塊,查詢器需要一個關于長期存儲中存儲桶的最新視圖。查詢器隻需要來自 bucket 的中繼資料資訊的,中繼資料包括塊内樣本的最小和最大時間戳。查詢器執行以下操作之一,以確定更新 bucket 視圖:
- 定期下載下傳 bucket 索引(預設)
- 定期掃描 bucket
Bucket 索引已啟用(預設)
當查詢器收到給定租戶的第一個查詢時,它會對 bucket 索引進行懶下載下傳。查詢器将 bucket 索引緩存在記憶體中,并定期更新。bucket 索引包含租戶的塊清單和塊删除标記。查詢器稍後使用塊清單和塊删除标記來定位給定查詢需要查詢的塊集。當查詢器在啟用 bucket 索引的情況下運作時,查詢器的啟動時間和對對象存儲的 API 調用量都會減少。我們建議您保持啟用 bucket 索引。
Bucket 索引已禁用
當禁用 bucket 索引時,查詢器會疊代存儲 bucket 以發現所有租戶的塊,并下載下傳每個塊的 meta.json 檔案。在這個初始 bucket 掃描階段,查詢器無法處理傳入的查詢,其 /ready ready 探測端點将不會傳回 HTTP 狀态代碼 200。運作時,查詢器定期疊代存儲桶以發現新的租戶和最近上載的塊。
查詢請求解析
連接配接到存儲網關
連接配接到接收器
支援中繼資料緩存
query-frontend
查詢前端是一個無狀态元件,它提供與查詢器相同的 API,并可用于加快讀取路徑。盡管查詢前端不是必需的,但我們建議您部署它。部署查詢前端時,應該向查詢前端而不是查詢器發出查詢請求。叢集中需要查詢器來執行查詢,在内部隊列中儲存查詢。在這種情況下,查詢器充當從隊列中提取作業、執行作業并将結果傳回到查詢前端進行聚合的工作者。要将查詢器與查詢前端連接配接,通過
-querier.frontend-address
配置,在使用高可用情況下建議部署至少 2 個查詢前端。
工作原理
隊列
查詢前端使用排隊機制來:
- 如果查詢失敗,請確定重試可能導緻查詢器記憶體不足(OOM)錯誤的大型查詢。這使管理者能夠為查詢提供不足的記憶體,或并行運作更多的小型查詢,這有助于降低總體擁有成本。
- 通過使用先進先出隊列在所有查詢器之間分發查詢,防止在單個查詢器上保護多個大型請求。
- 通過在租戶之間公平地安排查詢,防止單個租戶拒絕為其他租戶提供服務。
拆分
查詢前端可以将遠端查詢拆分為多個查詢。預設情況下,分割間隔為 24 小時。查詢前端在下遊查詢器中并行執行這些查詢,并将結果組合在一起。拆分可防止大型多天或多月查詢導緻查詢器記憶體不足錯誤,并加快查詢執行速度。
緩存
查詢前端緩存查詢結果并在後續查詢中重用它們。如果緩存的結果不完整,查詢前端将計算所需的部分查詢,并在下遊查詢器上并行執行它們。查詢前端可以選擇将查詢與其步驟參數對齊,以提高查詢結果的可緩存性。結果緩存由 Memcached 支援。
盡管将 step 參數與查詢時間範圍對齊可以提高 Mimir 的性能,但它違反了 Mimir 對 PromQL 的一緻性。如果 PromQL 一緻性不是優先事項,可以設定
-query-frontend.align-queries-with-step=true
。
store-gateway(資料存儲網關)
存儲網關元件是有狀态的,它查詢來自長期存儲的塊。在讀取路徑上,
querier
和
ruler
在處理查詢時使用存儲網關,無論查詢來自使用者還是來自正在評估的規則。為了在查詢時找到要查找的正确塊,存儲網關需要一個關于長期存儲中存儲桶的最新視圖。存儲網關使用以下選項之一更新存儲段視圖:
- 定期下載下傳 bucket 索引(預設)
- 定期掃描 bucket
工作原理
- bucket 索引啟用
- bucket 索引禁用
- 資料塊分片和複制
- 分片政策
- 自動忘記
- 區域意識
- 塊索引頭
- 索引頭懶加載
- 索引緩存
- inmemory
- memcached
- 中繼資料緩存
- 區塊緩存
Alertmanager
Mimir Alertmanager 為 Prometheus Alertmanagers 添加了多租戶支援和水準伸縮性。Mimir Alertmanager 是一個可選元件,它接受來自 Mimir 标尺的警報通知。Alertmanager 對警報通知進行重複資料消除和分組,并将其路由到通知通道,如電子郵件、PagerDuty 或 OpsGenie。
Override-exporter
Mimir 支援按租戶應用覆寫。許多覆寫配置了限制,以防止單個租戶使用過多資源。覆寫導出器元件将限制公開為普羅米修斯度量,以便營運商了解租戶與其限制的接近程度。
query-scheduler
查詢排程程式是一個可選的無狀态元件,它保留要執行的查詢隊列,并将工作負載配置設定給可用的查詢器。
工作原理
ruler
規則是一個可選元件,用于評估記錄和警報規則中定義的 PromQL 表達式。每個租戶都有一組記錄和警報規則,可以将這些規則分組到名稱空間中。
安裝
說明:安裝 mimir 需要在官方下載下傳這個二進制程式或者直接在 k8s 叢集裡面直接部署即可。在這裡以未啟用多租戶為介紹。
注意事項:
- target 預設為 all, 不包含可選元件 . 要啟用可選元件需要額外添加
- replication_factor 預設為 3, 如果隻有一台機器或者隻需要啟動一個執行個體 , 需要改為 1(單需要隻要 alertmanager 為 1 的時候隻能發送 1 條報警資訊 , 直到 2.3.1 版本官方都沒有解決)
裸機部署
- 準備配置檔案
alertmanager:
external_url: http://127.0.0.1:8080/alertmanager
sharding_ring:
replication_factor: 2
ingester:
ring:
replication_factor: 1
multitenancy_enabled: false
ruler:
alertmanager_url: http://127.0.0.1:8080/alertmanager
external_url: http://127.0.0.1:8080/ruler
query_frontend:
address: 127.0.0.1:9095
query_stats_enabled: true
rule_path: ./ruler/
ruler_storage:
filesystem:
dir: ./rules-storage
store_gateway:
sharding_ring:
replication_factor: 1
target: all,alertmanager,ruler
- 啟動服務
/usr/local/mimir/mimir-darwin-amd64 --config.file /usr/local/mimir/mimir.yaml
檢視狀态
-
服務啟動後可通過浏覽器打開檢視首頁
mimir_status
-
各服務運作狀态
running_status
-
檢視服務是否就緒
service_ready
-
檢視目前叢集節點
cluster_nodes
- 檢視多租戶
配置 Alertmanager
準備配置檔案
cat ./alertmanager.yaml
global:
resolve_timeout: 5m
http_config:
follow_redirects: true
enable_http2: true
smtp_from: [email protected]
smtp_hello: mimir
smtp_smarthost: smtp.qq.com:587
smtp_auth_username: [email protected]
smtp_require_tls: true
route:
receiver: email
group_by:
- alertname
continue: false
routes:
- receiver: email
group_by:
- alertname
matchers:
- severity="info"
mute_time_intervals:
- 夜間
continue: true
group_wait: 10s
group_interval: 5s
repeat_interval: 6h
inhibit_rules:
- source_match:
severity: warning
target_match:
severity: warning
equal:
- alertname
- instance
receivers:
- name: email
email_configs:
- send_resolved: true
to: [email protected]
from: [email protected]
hello: mimir
smarthost: smtp.qq.com:587
auth_username: [email protected]
headers:
From: [email protected]
Subject: '{{ template "email.default.subject" . }}'
To: [email protected]
html: '{{ template "email.default.html" . }}'
text: '{{ template "email.default.html" . }}'
require_tls: true
templates:
- email.default.html
mute_time_intervals:
- name: 夜間
time_intervals:
- times:
- start_time: "00:00"
end_time: "08:45"
- start_time: "21:30"
end_time: "23:59"
将配置檔案上傳到 mimir,預設 mimir 啟動後 alertmanager 的配置資訊是空的,報警器無法啟動,需要修改配置後才能啟動
$ mimirtool alertmanager load ./alertmanager.yaml --address http://127.0.0.1:8080 --id annoymous
配置 grafana 的 alertmanager
配置 grafana 的 prometheus
添加報警規則
配置多租戶
- 更改配置檔案中
multitenancy_enabled: true
- 上傳 alertmanager 配置檔案 (instance_id 一般為配置的 node 名稱 , 可以自定義)
$ mimirtool alertmanager load ./alertmanager.yaml --address http://127.0.0.1:8080 --id instance_id