雲原生在京東丨雲原生時代下的監控:如何基於雲原生進行指標採集?

image.png

從 Kubernetes 成爲容器管理領域的事實標準開始,基於雲原生也就是基於 Kubernetes 原生。在雲的體系下,基礎硬件基本上都被抽象化、模糊化,硬故障須要人爲干預的頻次在逐漸下降,健康檢查、失敗自愈、負載均衡等功能的提供,也使得簡單的、毀滅性的故障變少。而隨着服務的拆分和模塊的堆疊,不可描述的、模糊的、莫名其妙的故障卻比之前更加的頻繁。node

「看到指標」只是對於數據簡單的呈現,在目前雲的環境下,並不能高效地幫助咱們找到問題。而「可觀測性」體現的是對數據的再加工,旨在挖掘出數據背後隱藏的信息,不只僅停留在展示數據層面,更是通過對數據的解析和再組織,體現出數據的上下文信息。mysql

爲了達成「可觀測性」的目標,就須要更加_標準化、簡潔化的指標數據,以及更便捷的收集方式,更強更豐富的語義表達能力,更快更高效的存儲能力。_本篇文章將主要探討時序指標的採集結構和採集方式,數據也是指時序數據,存儲結構以及 tracing、log、event 等監控形式不在本次討論範圍以內。git

image.png

提到時序數據,讓咱們先看看幾個目前監控系統比較經常使用的時序數據庫:_opentsdb,influxdb,prometheus_ 等。github

經典的時序數據基本結構你們都是有統一認知的:web

  1. 惟一序列名標識,即指標名稱;
  2. 指標的標籤集,詳細描述指標的維度;
  3. 時間戳與數值對,詳細描述指標在某個時間點的值。

時序數據基本結構爲指標名稱 + 多個 kv 對的標籤集 + 時間戳 + 值,可是在細節上各家又各有不一樣。redis

image.png

1[
 2{
 3    "metric": "sys.cpu.nice",
 4    "timestamp": 1346846400,
 5    "value": 18,
 6    "tags": {
 7       "host": "web01",
 8       "dc": "lga"
 9    }
10},        
11{
12    "metric": "sys.cpu.nice",
13    "timestamp": 1346846400,
14    "value": 9,
15    "tags": {
16       "host": "web02",
17       "dc": "lga"
18    }
19}
20]

<左右滑動以查看完整代碼>
image.pngsql

opentsdb 使用你們耳熟能詳的 json 格式,多是用戶第一反應中結構化的時序數據結構。只要瞭解基本時序數據結構的人一眼就能知道各個字段的含義。數據庫

1<measurement>[,<tag_key>=<tag_value>[,<tag_key>= <tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]
2例如:
3cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000

<左右滑動以查看完整代碼>json

image.png

image.png

1metric_name [
2"{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
3] value [ timestamp ]
4例如:
5http_requests_total{method="post",code="200"} 1027 1395066363000

<左右滑動以查看完整代碼>網絡

image.png
5&wx_lazy=1&wx_co=1)

influxdb 和 prometheus 都使用了自定義文本格式的時序數據描述,經過固定的語法格式將 json 的樹狀層級結構打平,而且沒有語義的丟失,行級的表述形式更便於閱讀。

  • 文本格式優點

    ○ 更符合人類閱讀習慣

    ○ 行級的表述結構對文件讀取的內存優化更友好

    ○ 減小了層級的嵌套

  • 文本格式劣勢

    ○ 解析成本更高

    ○ 校驗相對更麻煩

image.png
wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

使用過 Prometheus 的同窗可能會注意到其實 Prometheus 的採集結構不是單行的,每類指標每每還伴隨着幾行註釋內容 ,其中主要是兩類HELP 和 TYPE ,分別表示指標的簡介說明和類型。格式大概是:

1# Anything you want to say
2# HELP http_requests_total The total number of HTTP requests.
3# TYPE http_requests_total counter
4http_requests_total{method="post",code="200"} 1027 1395066363000
5http_requests_total{method="post",code="400"}    3 1395066363000

<左右滑動以查看完整代碼>

Prometheus 主要支持4類指標類型:

  • Counter:只增不減的計數器。
  • Gauge:可增可減的數值。
  • Histogram:直方圖,分桶採樣。
  • Summary:數據彙總,分位數採樣。

其中 Counter 和 Gauge 很好理解,Histogram 和 Summary 可能一時間會讓人迷惑。其實 Histogram 和 Summary 都是爲了從不一樣維度解決和過濾長尾問題。

例如,我和首富的平均身價並不能真實反映出我本身的身價。所以分桶或者分位數才能更準確的描述數據真實的分佈狀態。

而 Histogram 和 Summary 主要區別就在於對分位數的計算上,Histogram  在客戶端只進行分桶計算,所以能夠在服務端進行總體的分位數計算。Summary 則是在客戶端環境下計算了分位數,所以失去了在總體視圖上進行分位數計算的可能性。官方也給出了 Histogram 和 Summary 的區別:

須要說明的是,截止到目前爲止的 Prometheus 版本 2.20.1,這些 metric types 僅僅使用在客戶端庫(client libraries)和傳輸協議(wire protocol)中,服務端暫時沒有記錄這些信息。因此若是你對一個 Gauge 類型的指標使用 histogram_quantile(0.9,xxx) 也是能夠的,只不過由於沒有 xxx_bucket 的存在,計算不出來值而已。

時序監控數據的採集,從監控端來看,數據獲取的形式只有兩種,pull 和 push,不一樣的採集方式也決定了部署方式的不一樣。

仍是經過 opentsdb,prometheus 來舉例,由於 influxdb 集羣版本方案爲商業版,暫不作討論。

![]image.png

image.png

上圖爲 opentsdb 架構圖 ,其中:

  • Servers:表示被採集數據的服務,C則是表示採集指標的工具,能夠理解爲 opensdb 的 agent,servers 經過C將數據推送到下游的 TSD。
  • TSD:對應實際進程名 TSDMain 是 opentsdb 組件,理解爲接收層,每一個TSD都是獨立的,沒有 master 和 slave 的區分,也沒有共享狀態。
  • HBase:opentsdb實際的最終數據存儲在 hbase 中。

從架構圖能夠看出,若是推送形式的數據量大量增加的狀況下,能夠經過多級組件,或者擴容無狀態的接收層等方式較爲簡單的進行吞吐量的升級。

image.png
&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

image.png

上圖爲 prometheus 架構圖,主要看下面幾個部分:

  • Prometheus Server:用於抓取和存儲時間序列化數據。
  • Exporters:主動拉取數據的插件。
  • Pushgateway:被動拉取數據的插件。

拉取的方式,一般是監控端定時從配置的各個被監控端的 Exporter 處拉取指標。這樣的設計方式能夠下降監控端與被監控端的耦合程度,被監控端不須要知道監控端的存在,這樣將指標發送的壓力從被監控端轉義到監控端。

對比一下 pull 和 push 方式各自的優劣勢:

  • pull 的優點

    ○ 上下游解耦

    ○ 被監控端不會由於 push 數據到監控端失敗,而致使自身不穩定。

    ○ 監控端自身的壓力狀況基本上能夠預測,下降由於被監控端突增的發送流量致使的自身風險,例如 DDoS。

    ○ 能夠作到被監控端的自動發現機制。

    ○ 主動權在監控端這邊,能夠更靈活的配置須要監控什麼,尤爲是在調試過程當中。

  • pull 的劣勢

    ○ 週期性不明顯,或者週期明顯短於採集週期的指標缺失精度。

    ○ 實時性較差。

    ○ 可能因爲防火牆等複雜的網絡環境設置,致使拉取不到數據。

    ○ 若是數據有缺失,很難進行補數據。

簡單對比了 pull 和 push 各自的特色,在雲原生環境中,prometheus 是目前的時序監控標準,爲何會選擇pull的形式,這裏有官方的解釋(https://prometheus.io/docs/in...)。

上面簡單介紹了一下從監控端視角看待數據採集方式的 pull 和 push 形式,而從被監控端來看,數據獲取的方式就多種多樣了,一般能夠分爲如下幾種類型:

  1. 默認採集
  2. 探測採集
  3. 組件採集
  4. 埋點採集

下面一一舉例說明。

image.png

默認採集一般是通俗意義上的全部人都會須要觀察的基礎指標,每每與業務沒有強關聯,例如 cpu、memory、disk、net 等等硬件或者系統指標。一般監控系統都會有特定的 agent 來固定採集這些指標,而在雲原生中很是方便的使用 node_exporter、CAdvisor、process-exporter,分別進行節點機器、容器以及進程的基礎監控。

image.png

探測採集主要是指從外部採集數據的方式例如域名監控、站點監控、端口監控等都屬於這一類。採集的方式對系統沒有侵入,由於對網絡的依賴比較強,因此一般會部署多個探測點,減小由於網絡問題形成的誤報,可是須要特別當心的是,必定要評估探測採集的頻次,不然很容易對被探測方形成請求壓力。

一般是指已經有現成的採集方案,只須要簡單的操做或者配置就能夠進行詳細的指標採集,例如 mysql 的監控,redis 的監控等。在雲原生環境中,這種採集方式比較常見,得益於 prometheus 的發展壯大,常見的組件採集 exporter 層出不窮,prometheus 官方認證的各類 exporter。對於如下比較特殊或者定製化的需求,也徹底能夠按照 /metrics 接口標準本身完成自定義 exporter 的編寫。

對於一個系統的關鍵性指標,自己的研發同窗是最有發言權的,經過埋點的方式能夠精準的獲取相關指標。在 prometheus 體系中能夠很是方便的使用 github.com/prometheus/client_* 的工具包來實現埋點採集。

image.png

本文對監控系統的第一個階段「採集」,從「採集結構」「採集方式」兩方面作了簡單的介紹和梳理。相比於以往,在雲原生的環境中,服務顆粒度拆分的更細緻,迭代效率更高,從開發到上線造成了更快節奏的反饋循環,這也要求監控系統可以更快速的反映出系統的異常,「採集結構」和「採集方式」雖然不是監控系統最核心的部分,可是簡潔的採集結構和便捷的採集方式也爲後續實現「可觀測性」提供了基礎。目前在雲原生環境中,使用 prometheus 能夠很是方便快捷的實現監控,雖然仍有許多工做須要作,例如集羣化、持久化存儲等,可是隨着 Thanos 等方案的出現,prometheus 也在漸漸豐滿中。

相關文章
相關標籤/搜索