#研發解決方案介紹#基於StatsD+Graphite的智能監控解決方案

鄭昀 基於李丹和劉奎的文檔 創建於2014/12/5
關鍵詞:監控、dashboard、PHP、graphite、statsd、whisper、carbon、grafana、influxdb、Python

本文檔適用人員:研發和運維員工

一,監控平臺要做到什麼程度?爲什麼要自己做?
  運維監控滿滿都是着各種開源系統以及它們的 Dashboard:
  • Zabbix
  • Nagios
  • Centreon
  • Logstash
  • Ganglia+Cacti
以及各種業務指標趨勢的 Dashboard。
  我們認爲,監控不能只是各種數據的採集和羅列,不僅僅是弄若干個報表並進一步配置成儀表盤,而是有一定智能,仿照我們日常的排查問題思路,建立一定規則,自動檢查,深度檢查,友情提示
 
  隨手舉一個例子:
規則:模仿我們發現問題後先檢查數據庫主從同步是否有問題的習慣
天機系統發現成單金額或驗證券數或短信發送條數環比大幅下降後,啓動檢查規則,
自動逐一檢查各種從庫的主從同步情況。
如果發現主從延遲超過閾值,則天機 DashBoard 應浮出兩條紅色警告提示(可點擊進入):
  • 5分鐘銷售數據環比下降50%
  • 某某從庫DBXXXX與主庫DBYYYY的同步延遲了300秒
如果發現主從同步失敗導致了同步停止,則應浮出兩條紅色警告提示(可點擊進入):
  • 5分鐘驗證券數環比下降40%
  • 某某從庫DBXXXX與主庫DBYYYY的同步停止,失敗原因爲:blabla
  就這樣,只有自己動手,才能把我們日常分析問題、定位問題的經驗變成一條條系統規則,還是那句話:
自動化纔是王道。
 
二,幾個通用技術問題
  大致想來,李丹劉奎還需要解決這麼幾個基礎問題:
2.1.繪圖所依賴的監控原始數據如何收集?如何加工?如何存儲?
不同運維指標和業務指標的時間粒度大小不一,1秒、1分鐘、5分鐘……
數據是業務方自行上報?還是主動採集?考慮一下可伸縮性:如果是數以百計物理機、成千上萬個虛擬機或容器的數以萬計指標呢?如果採集頻率非常高呢?
拿到原始數據後,原始數據至少還要經過 min/max/sum/count/mean/media……等計算才能變爲可視化圖表要展示的維度。
這些東西又怎麼存儲?
 
2.2.圖形如何繪製,各種指標如何疊加?
  在使用 Centreon 時,我們就抱怨不能把多個維度的指標自由組合後疊加在一張圖上看。是的,Centreon 能在一張圖上展示某個主機的它定義好的幾個指標,如下圖所示:
centreon圖例
圖1 centreon圖例
  但我們希望還能把不同主機的不同指標按我們的意願放在一張圖上繪製,也就是可配置的,這樣有利於排查問題,能快速看出趨勢變化和關聯關係。
  其次,繪圖得快,而且運維看的都是近乎實時的度量數據,怎麼才能足夠快。
 
2.3.拓撲關係如何繪製?
  拓撲關係很重要,最好能自動可視化,畢竟一圖勝過千言萬語。
  隨手舉個例子:
數據庫拓撲關係
在監控系統裏登記了 DB 的IP和分組後,其實已經可以探測到 DB 之間的主從關係(包括級聯關係)了,能自動繪製出登記的所有數據庫服務器之間的關係。舉例如下:
自動繪製數據庫拓撲
圖2 自動繪製數據庫拓撲
 
三,技術選型哲學
  選型兩個重要觀點:
  1. 不重複製造輪子;
  2. 既然找輪子,那這個輪子就應該只做一件事,且把它做到最好。
  可供選擇的方案有:
  1. grafana + influxdb
  2. statsd + graphite
  3. collectd + graphite
  4. grafana + graphite
 
3.1.StatsD
  2013年eBay 雲談及 OpenStack 的監控和報警時,提及了 statsd 和 graphite,如下圖所示:
ebay雲的監控報警
圖3 ebay雲的監控報警
  StatsD 是一個 NodeJs 的 daemon 程序,簡單輕巧,使用 UDP 協議,專門用來收集數據,收集完數據就發送到其他服務器進行處理。
 
3.2.Graphite

  Graphite 是一個企業級的監控工具,用 Python 編寫,採用 django 框架,sqlite 數據庫存儲,自有簡單文本協議通訊,繪圖功能強大。最初由 Chris Davis 在 Orbitz 工作時,作爲一個輔助項目開發的,最終成了一個監控基礎工具,如他所言,Graphite provides real-time visualization and storage of numeric time-series data,重點解決:

  • 實時可視化
  • 時間序列數據的存儲

嚴格地說,Graphite 只是一個根據數據繪圖的工具,數據收集通常由第三方工具或插件完成,它自帶了 carbon 和 whisper,還可根據其協議選用別的數據源供其繪圖。官方描述,預計用 Ceres 替代 Whisper。

graphite圖例

圖4 graphite圖例

  簡單的文本協議和強大的繪圖功能使得它可以方便地擴展到任何需要監控的系統上。豆瓣、Google、GitHub、Instagram、Uber等公司都用它。

 

3.3.CollectD

  C語言開發的 collectd 是一個較爲古老的工具,像 statsd 一樣它也做週期性收集統計數據,collectd 還管數據存儲。它能夠通過插件支持檢測各種各樣的系統信息,如數據庫、UPS。

  要想查看 collectd 收集的信息,還需要安裝 web 界面或者 Cacti,於是工作模式就是:

  collectd 作爲守護進程運行,每隔 10 秒收集信息,而 Cacti 每隔5分鐘運行一個 PHP 腳本來收集信息(兩者的時間間隔可配置)。

3.4.Influxdb
  InfluxDB 是一個開源分佈式時序、事件和指標數據庫。使用 Go 語言編寫,無需外部依賴。其設計目標是實現分佈式和水平伸縮擴展。向這個時間序列數據庫插入數據,每條數據都會自動附加上兩個字段,一個時間,一個序列號(用來作爲主鍵的)。
特點:
  • schemaless(無結構),可以是任意數量的列
  • Scalable
  • min, max, sum, count, mean, median 一系列函數,方便統計
  • Native HTTP API, 內置http支持,使用http讀寫
  • Powerful Query Language,類似SQL
  • Built-in Explorer,自帶管理工具
管理界面如下圖所示:
influxdb圖例
圖5 influxdb圖例
 

3.5.Grafana

 

  grafana 則類似 ES Kibana 的可視化面板,有着非常漂亮的圖表和佈局,目前支持 Graphite、Influxdb 和 Opentsdb) + influxdb(分佈式時序、事件和指標數據庫)等配搭。

  grafana 與 influxdb 整合後的效果如下圖所示:
grafana+influxdb整合圖例
圖6 grafana+influxdb整合圖例
 
四,最終選了statsd+graphite
  最終李丹和劉奎選擇的方案是:statsd(採集) + graphite(繪製, whisper 負責存儲)
  搭建了 Graphite 之後,你可以在它自帶的管理站點上看到所有指標的歷史數據,可以選時間範圍,如下圖所示:
graphite管理站點圖例
圖7 graphite管理站點圖例
  graphite 管理界面裏的圖形,請求格式如下所示:
http://graphite系統域名/render/?width=586&height=308&_salt=1410088306.115&target=stats.timers.mysql.172_16_999_999-3306.aborted_clients.upper_90
  如果我們的監控系統要把多個指標拼到一個圖形上渲染,則請求格式如下所示:

http://監控系統域名/db/createImage/target/%5B%22stats.timers.mysql.172_16_999_991-3306.com_select_persecond.upper%22%2C%22stats.timers.mysql.172_16_999_992-3306.com_select_persecond.upper%22%2C%22stats.timers.mysql.172_16_999_993-3306.com_select_persecond.upper%22%5D/from/-1hour.html?width=492&n=0.8623758849623238

  從而繪製出如下圖形,這就是我在前面2.2小節說想要的特性:
三個主機的指標繪製在一起
圖8 三個主機的指標繪製在一起
 
  Graphite 分爲三個組件:
  1. carbon - a Twisted daemon that listens for time-series data
  2. whisper - a simple database library for storing time-series data (similar in design to RRD)
  3. graphite webapp - A Django webapp that renders graphs on-demand using Cairo
  它的 High Level 圖如下所示:
graphite high level
圖9 graphite high level
  從上圖看出,Carbon 接到度量數據後,寫入 Whisper 庫裏,Graphite Webapp 去 Whisper 讀取數據,系統應該也做了一份緩存,所以你發送數據給 Carbon,立即就可以在 Webapp 中繪圖,這也是爲什麼在磁盤 I/O 反應不過來的時候,Webapp 的圖形仍能以接近實時的方式顯示的原因。
  下面兩張圖能幫助大家進一步理解 Graphite 裏 Carbon 和 Whisper 如何協同的。

graphite 邏輯圖

圖10 graphite 邏輯圖

Graphite 數據流轉圖

圖11 Graphite 數據流轉圖

 
五,數據的採集
  採集數據共有兩種方式:Get_Data 和 Push_Data。
  • 天機平臺主動拉數據,主要集中在數據庫的主從同步、數據庫的拓撲關係等這樣的關係型數據採集上。
  • 其他場景下,基本都需要採集單點狀態的數據,則由客戶端腳本(即 agent)獲取數據後,再推送到天機平臺。
 
  採集到的數據會走 UDP 協議發給 StatsD,由 StatsD 解析、提取、計算處理後,週期性地發送給 Graphite。
  數據推送到 Graphite 時,時間週期爲1分鐘,採集1分鐘內的業務數據按照 metric_path value timestamp\n 的格式發送。需要注意的是每次發送的數據必須以 \n 結尾,不能省略。
 
六,數據存儲的粒度
  首先,我們需要知道 statsD 默認10秒一個週期,可以通過修改 config.js 的 flushInterval 屬性變更。
 
  其次,Graphite 裏有一個 retention(保留)的概念,即明確數據精度以及丟棄多久之前的數據,在 /opt/graphite/conf/storage-schemas.conf 配置文件裏定義。retention 定義的表達式爲 frequency:history,每一個 retention 之間用英文逗號分隔。
  默認是按10秒一個數據的方式,存一天的數據,一天前的數據就沒了,如下面的配置所言:
[default_1min_for_1day]
pattern = .*
retentions = 10s:1d
  可以自定義 retentions,注意表達式裏每一個時間間隔必須是第一個的倍數,也就是說,第一個是10s,那麼第二個只能是10s的整數倍,以此類推。
  天機的數據庫監控的粒度爲:
[stats]
pattern = ^stats.*
retentions = 10s:1d,30s:7d,1m:28d,15m:5y
  依次解釋一下:
10s:1d——1天以內的數據是10秒爲一個值,
30s:7d——大於1天小於7天內的數據是以30秒爲一個值,
1m:28d——大於7天小於28天內的是以1分鐘爲一個值,
15m:5y——大於28天小於5年的,是以15分鐘爲一個值,
大於5年的數據丟棄。
  當把10秒的數據降爲1分鐘數據時,默認是算平均值,但你也可以按合計值、最大值、最小值等,反正都在 storage-aggregation.conf 裏配置。
  天機的業務指標監控的粒度爲:
[business_monitoring]
pattern = ^business_monitoring\.
retentions = 1m:5y
  爲什麼這麼定義?因爲天機要能繪製任意時間段裏粒度爲1分鐘的業務指標曲線圖,所以 Graphite 不能縮小精度。
 
七,天機的技術選型
  涉及到的開發語言有:
php,node.js,python,javascript
  涉及相關的框架和服務:
Yii,graphite,StatsD,D3js(數據可視化JS框架),pt-query-digest(分析MySQL慢查日誌)
  最後,天機系統的目標是以最有效率的方式查找到事故點,爲此要做到數據一體化和自動化。
 
-over-
參考資料:
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章