關於大型監控系統的高效能元件設計
以前有幸參與過一個分散式監控系統開發,有一些所謂的設計和開發的經驗,但苦於公司的內部系統無法開源,所以也就藏著掖著。 前兩天跟一途牛網、餓了麼的朋友胡扯了監控系統的事,這尼瑪正好點燃了我這高射炮,可以有個地好好釋放了下。 記得13年的時候,跟金山獵豹的斌哥聊過一些設計方案,後來聽他說也借鑑了一些思路,真假就不知道了。 趁著現在腦袋還清閒,開源的監控系統還沒有注意這一片思路前,先把自己的經驗共享出來。 這樣,如果有其他公司朋友如果想實現高效能的監控,或者是擴充套件現存的監控效能瓶頸, 可以適當的參考下我這文章。
首先老生常談一下分散式監控系統的簡單流程.
對於監控系統的瓶頸解決過程,我深有體會…. 這裡說個我經歷過的事情,我以前公司的zabbix監控系統就管理了將近3w+伺服器,包含雲主機。 對的,是3w個主機. 結果跟你想的一樣,確實經常出問題。 問題很是多樣化,有mysql io的問題,有zabbix server效能問題,有proxy卡頓,報警不及時。 總之造成這些問題的原因是量級過大引起的。
那麼後來是怎麼解決的?
mysql這一段做了分庫分表,儲存換成了ssd,資料庫引擎也更換為tokudbd。 報警不再採用同步阻塞的方式,而是使用我開發的report系統來傳送。 對於proxy中繼服務掛了咋辦? 明顯是相關的客戶端太多了,就做了一些分流,多開了幾個proxy。 對於zabbix server的瓶頸是怎麼解決的? 不好意思,沒在程式碼層次解決。 是根據業務線拆分成到不同的zabbix裡,也就是說多開了一組zabbix server。
那麼然後呢?
確實解決了這些問題,那麼為什麼沒有在程式碼層次解決?那麼他的效能瓶頸在哪裡? 我上面有說過,我有分散式監控系統的開發及優化的驗,所以很容易想到,也能找到他的瓶頸,比如閾值判斷回掃資料庫, 資料沒有聚合歸檔, 執行緒使用不合理等等…. 這本身是很不合理的設計。。。我自己也大範圍的改過zabbix server程式碼,最後因為各種問題不得不放棄。 說實話真心沒必要把時間耗盡在這zabbix裡,zabbix的程式碼有些雜亂不是很好理解,好在我沒花多少時間放在zabbix上。 大多數公司到了一定級別後,都會選擇性的開發監控系統,我一直都覺得監控系統開發說難也難,說簡單也簡單,這是廢話…. 只要把幾個瓶頸點和功能點想明白後,這都不是問題… 其實不管用是python,golang實現,都離不開對於監控系統的理解和優化。
另外,zabbix其實也是個商業組織,他們本身有zabbix優化方案的,雖然沒有說實現過程,但點出了他們使用了那些技術,比如redis,分散式任務佇列…
不扯了,說正題
對於監控的客戶來說,你需要實現這麼幾個功能.
- 註冊主機,併傳送心跳包
- 收集客戶端的各種資料, 系統類的資料可以從/proc拿到
- 需要開啟一個對localhost的介面,使用者可以自定義區sender資料.
- 預先設定工作執行緒數目,可根據任務的數量動態建立
- 需要設計一個良好的任務佇列,可以理解為任務生成器.
- 定時去獲取最新的監控列表及外掛
- 非同步, 可以使用condition的方式通知另一個執行緒去更新列表及外掛資訊並更正running , wait 任務配對資訊.
- 同步, 工作執行緒拿到任務後, 可檢視記憶體中該任務對應的狀態(繼續,停止,週期變化,有更新),再操作。
- agent需要有一個schduler的角色,來收縮擴充套件任務的變更.
- push邏輯一定要單獨寫,這樣解耦的目的是,工作執行緒只需要收集資料就可以了.
- 收集監控資料一定要做好timeout的配置,對於/proc不需要,涉及到網路io及大範圍掃描時,需加timeout.
- 模組內部可實現reload及自省反射模式
對於proxy中繼元件來說,他是減少服務端直接跟客戶端建立連結,在多個資料中心場景下,每個節點都跟server端建立連線也不是個好主意。 強烈推薦大家在proxy端進行judge判斷,然後把報警這個事告訴alarm,至於單條資訊實時推送,歸檔彙總計算完了後,會伴隨推鬆過去。 在proxy進行judege判斷,解決了server不小的壓力。
對於judge元件來說,他主要是實現判斷客戶端提交的資料是否達到了閾值條件,是則觸發alarm. judge系統不可能簡單就判斷一次,也肯定不能就判斷一次,這樣很容易就造成報警氾濫。 我們需要實現下面幾個功能
- 簡單判斷
- 時間區間次數判斷
- 多久內只發一次
在詳細描述他之前,我們要知道judge的不合理會成為server端的一個效能瓶頸, 比如zabbix每次判斷狀態的時候都回掃資料庫…. 你完全可以把資料放到快取裡面,但你們肯定會問連續三次觸發報警,怎麼實現… 60秒內觸發三次閾值怎麼判斷. 你可以使用redis sorted set來實現,把時間戳作為score,數值作為值.
這裡提一下服務序號產生器制,為什麼需要服務序號產生器制? 當時開發這元件的主要目的是為了收集客戶端的心跳,如果他沒有心跳了,那麼就說明他掛了或者是網路有異常.
我們舉個例子,你監控流量,server 端收集到了後,可以進行閾值判斷。 但是如果過了很久還是沒有傳送給你,你靠什麼來判斷閾值,或者是 得到他長時間沒給我資訊這個事件。 我們這裡需要明確一個點, 在開發監控系統的時候,就要設計server端的timer事件只關心agent心跳,對於該客戶端的記憶體,流量,負載都不會註冊timer事件。 因為我只要知道你沒來心跳,那麼別的資訊也過不來。
服務註冊還可以進行服務歸類,對於業務專案來說,可以看到他所屬的專案的服務樹狀態,也就是說可以看到專案的整體狀態。 這裡不限於agent級別,你可以讓多個程式都註冊上來,如果某個程式被oom了,那麼你可以在前端的服務樹裡看到他的消失。 這裡可以使用 zookeeper,etcd做服務註冊, 我推薦使用etcd,雖然etcd沒有zookeeper那種臨時session的概念,但ttl timeout足夠用了,另外etcd的原始碼實現也夠簡單和高效,很是養眼。 友情提示下,redis是沒有那種expire watch機制,因為redis 過期key掃描力度很粗,在stackoverflow看過一個回覆,說是在redis裡把expire的掃描任務改成每秒執行,然後使用brpop事件的方式來達到watch,有些意思。
alarm ,就是報警,沒啥好說的,只需要跟judge解耦構建成非同步方式就可以了,另外別像zabbix那樣把事件放到mysql,這樣多個執行緒去讀取的時候,還要考慮資料安全問題。
- 微信
- 郵件
- 簡訊
- 電話
store, 簡單說他是入庫的模組,高階說法是歸檔聚合計算模組. 可想而知,高階說法明顯複雜的多. 很多監控系統的前段為毛那麼慢? 就算用了ssd之後雖然有明顯提高,但瓶頸出現在mysql計算上。 比如5秒一個資料,你想看一個月的圖表趨勢,怎麼算?很明顯這要經過大量的臨時的聚合計算。 我們不能怎麼搞? 我們需要提前入庫的時候,就要計算好聚合點。 比如一堆的5秒資料,我們按照他們當前的分鐘數來聚合成15秒點,30秒的點,60秒的點….
監控系統的聚合歸檔怎麼實現?
還是使用redis sorted set有序佇列,每個主機的監控專案為一個佇列,這個佇列可以跟judge一樣. 取一分鐘,然後15 秒一組,30 一組,60秒一組,計算avg後入庫。
為什麼不用45秒? 因為涉及到多個分鐘段。 不好實現。
怕影響時間區間閾值判斷,可以去前三分鐘之前的一段資料。 每次都是 0- 三分前 !
那麼最後歸檔的資料放在哪裡, mysql ? ElasticSearch , opentsdb, influxdb ?
mysql在量級不是很大的時候是沒有問題,當出現效能瓶頸可以讀寫分離,再不行可以對歷史表進行時間分表。 記得在邏輯裡多加cache,如果條件可以的話,直接用ssd.
influxdb我用過很深,在樂視的時候就在用,也看過部分的程式碼,因為是golang實現的,程式碼很是整潔,看程式碼的過程中也學到了架構上的設計。 最後我對他的印象是不堪大用,如果你的資料過500G,不管你使用leveldb,rocksdb,hyperdb都有些徒勞,效能縮水很厲害. 至於他的分散式? 我就不說了,我寫過不少influxdb的文章,大家可以看看, http://xiaorui.cc/tag/influxdb/
大多數公司都會採用mysql,如果你的公司有Elasticsearch和hbase的基礎服務,那麼你可以在這基礎上構建監控儲存系統。 如果沒有這些基礎環境,單純為了監控系統起這些服務,後期又擴充套件,不好說,看公司支援力度了。
我對於hbase和Elasticsearch都用了將今兩年的時間, 不太推薦使用hbase,這裡說明下我們不是直接使用hbase,而是使用在hbase之上封裝的opentsdb. opentsdb就是為了監控服務而存在的. 如果你的系統不是java開發的,那麼操作hbase不外乎中介軟體的方法,像thrift server,opentsdb的tsd都可以算是代理,thrift提供的是最原始的hbase的方法,而opentsdb提供了類似監控模板的方法,又因為opentsdb的效能不弱,所以是有不少公司選擇它,比如阿里, 當然人家那java黨多,神也多,可以深度挖坑埋坑….
hbase本身是不支援二級索引的,他的索引只有rowkey行健,往往rowkey裡含有主機的標識資訊及時間資訊,像這樣該組監控資料產生了時序或者單調(遞增/遞減)行鍵,導致連續到來的資料會被分配到統一region中,一堆資料集中到一個region,雖然不能更用應用hbase的優勢,但這樣介紹了hbase之間的一些協作,像監控資料本身也沒啥大量計算,另外使用hbase的時候,預先要設定region,要不然每次都要分裂分配region很是影響效能。 你每次從hbase想獲取一個時間段資料,都是scan的過程,如果你想做一些各方面的統計,那就要寫Mapreduce了。
我這裡推薦大家使用ElasticSearch作為監控資料的儲存,他的好處多多,首先他的查詢效能沒得說,可以像hbase那樣橫向擴充套件,可以像mysql那樣多個欄位查詢,可以隨意搭配欄位進行查詢,圖示展現可以直接使用grafana,kibana,經過一年的使用發現,grafana真的很適合做監控系統的前端展現。 這時候對於你來說,只需要開發系統系統的管理頁面就可以了,當然如果要規範化,儘量還是自己開發監控的前端。 不要試圖修改grafana的前端原始碼,不容易呀,教訓呀。
記得給query加快取,以後資料可以從redis獲取,需要控制好快取的超時,對於一個小時之前的資料,可以快取個10天,對於當前的資料可以選擇性的快取。
總的來說描述有些粗了, 有時間再好好細化下,由於篇幅原因沒有聊到前端方面的優化,後期陸續更新。
相關文章
- DevOps專題 | 大型企業級監控系統設計dev
- 監控系統元件元件
- 基於系統融合的統一監控平臺設計
- 視訊監控系統的設計
- Flutter異常監控 - 伍 | 關於異常監控框架設計的思考Flutter框架
- 大型網站背後的高效能系統架構設計網站架構
- 【系統設計】指標監控和告警系統指標
- 關於系統分析設計
- 蘋果系統用於系統監控和管理的命令蘋果
- 基於 Prometheus 的監控系統實踐Prometheus
- 大型監控網路系統規劃ip地址例項
- 關於SSH中對於action的監聽問題(關於系統計數)
- 關於相親原始碼的監控系統搭建,你瞭解多少?原始碼
- 關於許可權系統的設計
- [原創]效能監控之大型日誌分析和監控系統,助力提升效能測試的有效手段
- JavaWeb的監控系統JavaWeb
- 基於LORA SX1278的溫度監控控制系統開發設計-硬體方案設計
- 基於 Flink+Pravega 的遊戲伺服器監控與調節系統設計遊戲伺服器
- 打造雲原生大型分散式監控系統(四): Kvass+Thanos 監控超大規模容器叢集分散式
- 關於這樣的系統設計,求問?
- 續:關於許可權系統的設計
- Mysql 監控系統MySql
- 關於 “監控此主題”?
- 雪亮工程視訊監控系統建設方案重點人員監控系統開發
- 大型企業能源管理監控系統開發,線上監測平臺搭建方案
- 關於郵件監控的問題
- 關於高效能聊天系統的一個問題
- 運維監控系統 PIGOSS BSM的監控策略運維Go
- 打造雲原生大型分散式監控系統 (三): Thanos 部署與實踐分散式
- 基於 Zabbix 系統監控 Windows、Linux、VMwareWindowsLinux
- 實時監控系統,統一監控企業APIAPI
- 調研位元組碼插樁技術,用於系統監控設計和實現
- 關於雲控系統的各種細節
- 關於系統許可權的設計-位操作
- 基於飛信對系統計劃任務crontab報警監控
- 課程報名 | 監控系統怎麼設計,才能高可用?
- Mac系統監控工具Mac
- 打造前端監控系統前端