本節討論 Prometheus 的核心,多維數據模型。我們先來看一個例子。
比如要監控容器 webapp1
的內存使用情況,最傳統和典型的方法是定義一個指標 container_memory_usage_bytes_webapp1
來記錄 webapp1
的內存使用數據。假如每1分鍾取一次樣,那么在數據庫里就會有類似下面的記錄。
好,現在需求發生了點變化,我們需要知道所有 webapp 容器的內存使用情況。如果還是采用前面的方法,就不得不增加新的指標 container_memory_usage_bytes_webapp2
、container_memory_usage_bytes_webapp3
…
像 Graphite 這類更高級的監控方案采用了更為優雅的層次化數據模型。為了滿足上面的需求,Graphite 會定義指標 container.memory_usage_bytes.webapp1
、container.memory_usage_bytes.webapp2
、container.memory_usage_bytes.webapp3
…
然后就可以用 container.memory_usage_bytes.webapp*
獲取所有的 webapp 的內存使用數據。
此外,Graphite 還支持 sum()
等函數對指標進行計算和處理,比如 sum(container.memory_usage_bytes.webapp*)
可以得到所有 webapp 容器占用的總內存量。
目前為止問題處理得都很好。但客戶總是會提出更多的需求:現在不僅要按容器名字統計內存使用量,還要按鏡像來統計;或者想對比一下某一組容器在生產環境和測試環境中對內存使用的不同情況。
當然你可以說:只要定義更多的指標就能滿足這些需求。比如 container.memory_usage_bytes.image1.webapp1
、container.memory_usage_bytes.webapp1.prod
等。
但問題在於我們沒辦法提前預知客戶要用這些數據回答怎樣的問題,所以我們沒辦法提前定義好所有的指標。
下面來看看 Prometheus 的解決方案。
Prometheus 只需要定義一個全局的指標 container_memory_usage_bytes
,然后通過添加不同的維度數據來滿足不同的業務需求。
比如對於前面 webapp1 的三條取樣數據,轉換成 Prometheus 多維數據將變成:
后面三列 container_name
、image
、env
就是數據的三個維度。想象一下,如果不同 env
(prod、test、dev),不同 image
(mycom/webapp:1.2、mycom/webapp:1.3)的容器,它們的內存使用數據中標注了這三個維度信息,那么將能滿足很多業務需求,比如:
-
計算 webapp2 的平均內存使用情況:avg(container_memory_usage_bytes{container_name=“webapp2”})
-
計算運行 mycom/webapp:1.3 鏡像的所有容器內存使用總量:sum(container_memory_usage_bytes{image=“mycom/webapp:1.3”})
-
統計不同運行環境中 webapp 容器內存使用總量:sum(container_memory_usage_bytes{container_name=~“webapp”}) by (env)
這里只列了幾個例子,不過已經能夠說明 Prometheus 數據模型的優勢了:
-
通過維度對數據進行說明,附加更多的業務信息,進而滿足不同業務的需求。同時維度是可以動態添加的,比如再給數據加上一個
user
維度,就可以按用戶來統計容器內存使用量了。 -
Prometheus 豐富的查詢語言能夠靈活、充分地挖掘數據的價值。前面示例中的 avg、sum、by 只是查詢語言中很小的一部分功能,已經為我們展現了 Prometheus 對多維數據進行分片、聚合的強大能力。
現在我們已經知道 Prometheus 的強大之處了,再 NB 的東西也得落地,下一節就開始實踐。
書籍:
1.《每天5分鍾玩轉Docker容器技術》
https://item.jd.com/16936307278.html
2.《每天5分鍾玩轉OpenStack》
https://item.jd.com/12086376.html