新手也能看懂的監控報警系統架構設計
對于監控報警這一塊內容我想過很多次要從哪個方面講,因為監控報警在現在已經是互聯網公司一個通用的產品。
而大數據的監控報警只是其中的一系列報警規則子集,雖然這個子集很復雜。
有趣的是,報警系統的下層數據存儲引擎,也是歸類于大數據存儲的范疇。所以我打算從這樣的大綱來展開本文:
- 針對大數據集群,監控報警的特點
- 監控報警系統發展的歷史及業務背景
- 監控報警系統的通用架構
- 監控報警系統細節分析
- 總結
針對大數據集群,監控報警的特點
圖 1:針對大數據集群的不同特性,監控報警的特點
像大數據基礎設施這種部門,不可能配制專門的測試工程師,那么這么多的機器、服務以及應用要如何很好地運轉下去呢?
這就需要一套強大的“自動化監控報警系統”。監控報警這一塊,不同的公司應對方案是不同的。
對于大公司、小公司、創業公司,它們根據自己的實際情況選擇對于自己合理的解決方案。
監控報警系統發展歷史及業務背景
市面上的監控報警系統多種多樣,但越是眼花繚亂的市場,越要睜大眼睛,看其本質,剝其筋骨,找一款適合自己的解決方案。
網上有很多講述公司內部監控報警系統的文章,都提到了自家監控系統的實現,但都是直接講解了實現的細節,沒有講骨架、背景。
我感覺對于新入行的程序員來說會略顯生硬,對于想了解監控報警系統內部運作原理的人來說,架構邏輯也不夠清晰。所以,我寫了這篇既講背景,又講骨架的文章。
首先是背景,我們先來談談軟件工程。在很早以前,軟件開發的技術團隊在做迭代開發時,一般是要經歷這樣的開發流程:
- 需求分析
- 原型/功能設計
- 測試用例設計(Tdd 測試驅動的開發)
- 開發人員完成功能,部署測試環境
- 測試按照測試用例做測試
- 如果在測試時,發現 Bug,則回滾給開發重新 Fix
- 如果測試沒測試出 Bug,則上線生產環境
- 等線上真正有用戶發現了 Bug,好心的用戶會匯報 Bug,聯系客服人員
這種流程會導致什么問題呢?一般簡單的“顯式”Bug,比如“網站關鍵頁面打不開了”、“網站下單支付功能一直失敗”等等這類錯誤。
用戶和公司都能在相對的一段時間內發現問題,然后問題被重新整理報修為 Bug,修復、回滾。
而一些“隱式”Bug,比如“網站越來越慢了”、“支付功能要 30 秒才能成功”、“有時成功,有時失敗”、“短信驗證碼在產品上線了一周后,變得要 25 秒才能發送到客戶手機上”。
這類問題,有時并不影響業務邏輯的正常運轉,但系統內部肯定是已經出現問題了。
有時長期積累下去,會慢慢暴露出更多問題,最后導致核心業務的宕機;有時甚至就是產品性能上線后本身就很差,由于某次上線的“代碼/配置”變更導致。這種“隱式”的 Bug 也會影響用戶體驗。
測試發現顯式 Bug,what abou the 隱式 Bug?隨著互聯網的發展,各大互聯網公司對業務穩定、可靠性的要求越來越高。
但公司的業務線是越來越多的,測試工程師不可能人肉去干無窮盡的手工測試,每天 24 小時一直盯著產品。
作為公司,更是希望這種隱式的 Bug 不要由用戶報告出來,最好是在內部 “快速”發現問題、“自動”發現問題、要比“用戶”早發現問題。這就逼迫開創了了“自動化周期性線上測試”。
“早期的自動化測試”,只發生在軟件上線之前。比如開發提交了新的功能之后,公司內會有 Jenkins 這種持續集成工具自動觸發去跑測試用例。
用例包括開發人員的“單元(白盒)測試”,以及測試人員寫的“腳本(黑盒)測試”。要求全部通過之后,方能部署到“生產”環境。
這種方式,能發現大部分的“顯示”Bug,但是很難發現“隱式”Bug。倘若有些程序有內存泄漏,并不會第一時間馬上崩潰,可能是跑了一個星期,甚至一個月才產生問題。
“自動化周期性線上測試”,解決隱式的 Bug,在產品上線后,持續地針對線上環境的多種指標,進行長期觀測,進行規律判斷來發現異常。
如果有潛在的異常,那么某些監控指標會出現問題。還有一些異常指標在暴露時,如果能第一時間聯系到對應產品的“負責人”,馬上進行補救,從長期來看,對產品的口碑會有一個很大的提升。
比如:一個電商網站的支付頁面,響應速度持續地超過 5s,遠大于長期的平均值(2s),在這種現象連續出現 5 次時,報警給這一塊的研發人員,其發現程序有資源泄漏導致機器變慢,然后先重啟了部分服務,保證用戶速度提上來,之后馬上組織對此功能進行 Hotfix,最終解決問題。
監控報警系統的通用架構
之前講了“自動化周期性線上測試”的產生歷史原因及背景。看起來,這是時代的發展倒逼技術界而產生的“技術更替”。
在往后的內容,我們把“自動化周期性線上測試”系統,稱為“監控報警”系統。因為它代替了人去“監控”,代替了測試工程師去“報告問題”。
圖 2:監控報警信息流
監控報警我認為分為四大塊:
- 收集數據
- 存儲數據(時間序列的存儲)
- 報警規則
- 報警行為
下圖監控系統是基本骨架,再細化一下,整個架構圖會變成下面這個樣子:
圖 3:監控報警系統架構圖
監控報警系統細節分析
收集數據
收集數據,我想這篇經典的《Measure Anything,Measure Everything》(https://www.tuicool.com/articles/A3AFvu6),是開啟了新時代“數據驅動”的監控運維思想的一篇博文,大家可以讀一讀。
這里面講到的思想,也符合我這一系列文章的主旨:讓一切人的決策基于數據。
文章中提到,企業級的監控數據,通常包括如下三類:
- 網絡數據,包括骨干交換機,核心交換機等硬件設備。
- 服務器數據,包括服務器的 CPU、內存、硬盤的各項使用數據。
- 應用數據。
應用數據是這三者中最難的,但也是最重要的。應用數據是和業務邏輯緊密相關的數據,業務邏輯變了,應用數據的收集也會變化。
在應用數據這一塊,有一個開源項目叫 Statsd,它催生了“應用數據收集標準” <github-statsd 應用數據收集標準>。
https://github.com/etsy/statsd/blob/master/docs/metric_types.md
在這里我也簡單提一下:
- 累加值(Counting) gorets:1 | c
- 服務耗時(Timing) glork:320 | ms | @0.1
- 指標值(Gauges) gaugor:333 | g
字符串的第一部分,就是 "METRIC",用冒號隔開的左邊是“METRIC_KEY”,右邊是“METRIC_VALUE”,豎線右邊的部分是“數據類型”。
存儲數據
監控報警的數據,全部都是圍繞“監控指標的值隨時間變化的趨勢”這一目標而設計的。每一項監控指標數據序列都是天然的按“時間排序”的,這是其特點。
業界管存儲這種數據結構的工具叫“時間序列數據庫”。這是一種專有數據庫,并非像 RDBMS(關系型數據庫)是一種通用的 SQL-LIKE 的數據庫。
市面上有很多很多的基于時間序列的數據庫,不論其底層的數據結構實現是什么樣子,時間序列存儲的本質數據結構永遠都是:
Map< METRIC_KEY , sortedMap<timestamp, METRIC_VALUE >>
不同的底層實現都是在上面這個數據結構的一些點上有不同的擴展,比如:
- s1.在 METRIC_KEY 的分片邏輯,實現上不同:選取的分片是一致性哈希,還是求余哈希。
- s2.SortedMap 的實現不同,本質上是一個按 Timestamp 排序的序列。
- s3.讀寫的偏好略有不同。
在這里我不會著重去講具體的每一個時間序列的數據庫以及其底層數據結構的實現。
在技術選型時既要考慮技術的痛點,也需要考慮業務上的痛點,業務場景定下來了,技術選型才能定。
那么根據業務場景,又有了其他幾個選型點:
- s4.Metrics 是否會無限增加?
- s5.Metrics 保留的時間跨度有多長?
- s6.上層的業務報警,有多重要?
為了解決技術選型 SELECT,s1-s6,我拿一些例子來說明:
Metrics 是否會無限增加,保留時長
專有系統,即解決某一特定領域問題的時間序列存儲,Metric key 不會無限增長。
比如我們管理 Hadoop 的套件 Cloudera-Manager 或 Hortonworks 的 Ambari,都有自帶的監控報警系統。
他們都是把數據存儲在本地的磁盤上,相當于是一個本地的數據庫。單機版數據庫的問題就是受單機硬盤的物理上限限制。
好在 Hadoop 技術棧的監控指標是有限的、收斂的,且這些數據也大多只需要保留 1 個月。因此“Hadoop 監控系統們”的單機存儲空間是可控的。
專有系統,一定是服務于一個成熟的“內聚產品”。通用監控報警系統,Metric key 會無限增長。
如《Measure Anything,Measure Everything》提到,公司每個業務線 Team 都會把自己的應用數據發送到統一的指標數據存儲中。
隨著業務線、監控指標的增長,時間序列存儲的壓力是無限增加的,且數據的保留時長不定,很有可能是無限長(每個應用都有其特殊性,不可估量)。這就要求底層的數據存儲必須支持“無限水平擴展”。
SortedMap 實現和讀寫偏好
SortedMap 即全局排序的映射表,它的實現更要由報警監控的實際需求出發了。
專有系統,由于是有限的指標,且搜集數據的頻率也不會特別變態的高,那么同一時刻寫入的數據量應該是可控的。此時 B+Tree、SkipList 都是很好的實現方式。
而通用系統,監控指標會無限增加,有些指標采集需求的頻率可達幾十毫秒。這么高頻的并發寫入需求,一般使用 lSM Tree 來實現。
上層的業務報警,有多重要(HA & 高可用性)
任何時候,監控報警系統都必須可用,必須可以容忍一部分機器掛掉。其不能因為某臺機器、某個進程掛掉而導致整個監控報警體系都宕掉。
SPOF :https://en.wikipedia.org/wiki/Single_point_of_failure
監控報警系統是用來“觀測公司內部的所有業務是否正常運轉”的,所有產品的第一時間救命稻草也就都壓在了“監控報警”系統上了。
它掛了,公司所有產品出問題都反映不出來了。所以像基于單機版本數據存儲的時間序列是不能滿足企業級要求的。一定要選擇高可用 HA(High Available)的數據存儲解決方案。
而對于小型創業公司,可以在業務初期和高速增長前期暫時放棄過高的可靠可用性,先使用諸如“磁盤 Raid、定期備份、做數據庫級別的主從切換”等簡單易實施的技術來快速滿足輕量級的業務需求。
最后,附上一些時間序列數據庫總結引用的論文及文章:
wiki : Time series database
https://blog.outlyer.com/top10-open-source-time-series-databases
報警規則
報警規則模塊,首先,是天然個性的。為什么呢?按什么規則報警,顯然是和每個公司的具體業務綁定的。
而規則是基于對歷史數據的分析、度量。這牽扯到公司業務的個性化,本篇文章對個性化的業務細節不做過多的贅述。
我們看看看報警規則有哪些通用的技術點:
High-Available 的規則周期檢查
企業級的應用,最強調的就是高可用 HA,必須避免單點故障 SPOF。“報警規則模塊”發生問題了,仍然會導致“監控報警”系統失效。
一般來說,報警規則都是周期性觸發的。因此需要有一個“類Cron Job”的調度器。
這類調度系統的 HA 設計可以參考“Azkaban” 和 “Quartz”:
- Azkaban:https://azkaban.github.io/
- Quartz:http://www.quartz-scheduler.org/
調度系統的 HA 設計主要分為“規則數據庫的高可用”和“調度 Sever 的高可用”兩方面:
- 數據庫高可用通過 Master-Slave 的主從實現。
- 調度 Server 的高可用,如果有狀態,則使用 zk/etcd 來做高可用;如果無狀態,那就啟動多個調度服務器好了。根據調度規則,制定一定的分片策略,不算困難。
報警規則定義
在我觀察了一系列的監控報警產品后,大致歸納出兩種“報警規則”的定義實現方式:
- 基于“規則表達式的”。
- 基于直接“腳本&編程”的。
基于規則表達式的:在熟悉了表達式語言后,比較容易編寫,但靈活性差。在實現復雜的報警規則時比較難,一般適用于簡單的報警規則。
比如當某一、二個觀測指標到達閾值時觸發,如下圖:
Prometheus:Alerting rules | Prometheus
圖 4:Promethus 基于規則設定報警的例子
還有基于可視化配置規則的,比如 Zabbix 的 Trigger 配置:Zabbix Documentation 3.2。
圖 5:Zabbix 的可視化規則配置
Grafana 在 4.0 之后,也有了基于規則的簡單報警功能:Alerting Engine & Rules Guide,如下圖:
圖 6:Grafana4.0 基于規則的報警 UI .1
圖 7:Grafana4.0 基于規則的報警 UI .2
基于“腳本/編程”的,這種類型的規則定義,提供了無限的靈活性。因為“可編程”,就等于可以“do everything”。
但也有一些壞處,比如:又多引入了一個外部依賴:代碼管理庫,且意味著又要為另一套系統做高可用 HA,一般為公司內部的代碼管理使用 Github/Gitlab。
想快速修改報警規則時,流程會相對慢,因為要經過代碼的修改,Merge,最后 Submit。
報警規則“腳本”定義的例子: 收集兩個數據源的數據,根據自定義規則,判斷指標是否異常,如果有異常,先進行“重啟”行為,緩解線上壓力,再發出報警給相關工程師,追查真正原因。
這種稍微復雜的報警規則,用編程腳本的方式實現起來毫無壓力,而如果要用基于規則語言的報警,則比較困難,甚至是不可能實現的。
圖 8:基于“腳本”的報警規則,定義函數
圖 9:基于“腳本&編程”的報警規則例子
報警行為
大家可能會問,報警行為有什么好講的呢? 不外乎就是在報警規則觸發后,通過電話、微信、短信、郵件等媒介找到正確的負責人,這聽起來很簡單啊。
好,我們繼續把應用場景想的豐富一些:比如我們的 Hadoop 架構組,有 HDFS、Yarn、Hive、HBase、Zookeeper、Spark、Presto、Impala、Hue、Cloudera Manager……OK,不要再講了。
這么多組件,一個人能運維的過來嗎?是否需要組內的多個人分工呢?每個人一個星期?
檢測 Hadoop Namenode 健康的報警每 5 分鐘一次,是否每一次檢測失敗了都要報警?會不會有誤報?
第一次異常報警后,工程師已經在排查問題了,這時連續的第二次、第三次檢測異常,是否需要連續的打電話去打擾工程師? 那么,連續幾次抑制報警呢?
哪些報警是非常重要的,白天晚上都必須打電話通知;哪些是相對重要的,白天打電話,晚上可以發一封郵件、短信先通知問題;哪些是次要的,可以只發一封郵件的。
有時候檢測程序也會因為一些“噪音”產生抖動,比如檢測網頁打開速度限制在 2ms,但是有一次訪問就是因為網絡鏈路的抖動達到了 50ms,那是否就應該直接報警呢? 是不是連續 3-5 次的數據全部超標,確認問題之后再報警呢?
報警行為軟件,分為“自研”和“第三方”兩條路:
- 自研開發,這條路適合有強大復雜報警行為規則的大公司。包括報警行為規則的復雜和報警媒介的復雜兩方面。
每一家公司使用的內網辦公聊天軟件、郵件系統可能都不一樣,都會有獨特的場景需要集成。
每一家公司、每一個組的報警行為可能也不一樣,有的要 7*24 小時,有的只需要白天發封郵件,有的甚至只需要在工作日的白天發封郵件。
- 第三方軟件,中小型公司,創業公司,更適合使用第三方軟件。目前據我了解,灣區的公司,大多使用 Pagerduty,可參考鏈接了解詳情:https://www.pagerduty.com/。
而這款產品并沒有做中文的本地化,本土的軟件,還沒有一款殺手級的存在于市場。我找了一圈,找到了 Oneapm 公司的 One-Alert(http://www.110monitor.com/),試了試 Demo 還不錯。
個人意見:這一塊的需求會越來越大,希望國內能有靠譜像樣的公司做起來,共同推進國內的“監控報警”市場發展。
總結
我整理了一張表,描述常見的“監控報警”領域的開源產品,落在哪個區間:
大家在做技術選型時,一定要看的長遠,多想想未來的需求,不能只著眼于快速交付。同時,也希望國內能有專注于“報警行為”的公司出現。
作者:汪涉洋
簡介:來自美國視頻網站 hulu 的工程師,畢業于北京理工大學計算機專業,目前從事大數據基礎架構方面的工作,個人知乎專欄“大數據SRE的總結”:http://dwz.cn/7ygSgc。