上古十大神器之一天機鏡:天機鏡又名昆侖鏡。昆侖山西王母所有,能洞察天機,知曉古今!
1. 動機
在業務系統開發的前期,我們往往只專注到業務邏輯,而忽略了對系統本身的監控。 對硬件資源的監控運維同學提供的ganglia以及ZENOSS 能很好的滿足我們的需求,監控機器的磁盤、cpu負載,內存,load,連接數等等。但是介於核心功能以及硬件指標之間的一部分監控數據目前是空白的,比如服務本身的負載,jvm使用,qps,tps,隊列大小,等等。這些數據本不屬於業務功能,但是對后續服務擴容,定位問題能夠提供良好的依據。
天機鏡的誕生就是為了解決這部分需求,我們提供一個輕量級的數據采集接口,采集業務系統的各種指標,並將這些指標以圖表的形式展示出來, 能夠直觀清晰的顯示各個指標信息。我們也提供了對用戶所關注的指標的實時監控和報警的功能,同時還可以為用戶提供定制報表的服務。
目前,天機鏡為大數據應用的上百個監控場景提供了服務,每天收集5億條監控數據,持久存儲可達30天。然而目前僅使用四個節點作為存儲,集群依然可以再增加三倍的業務量。
2. 功能設計
天機鏡提供了圖形化的查詢界面,以曲線的形式呈現數據,下面是若干用例:
圖1 Kafka集群全局負載均衡對比圖(上面顯示了不同ip的字節流量)
圖2. storm應用內存泄露案例(曲線名稱為ip::pid,可以看出106的進程穩定,而107的進程內存到一定值后OOM,然后重啟,進程號改變)
圖3. 某方法調用耗時監控(上圖的點的意義是最近樣本池中99.9%的調用都在0.19s以下,當然可以看平均值、p50、p75、p98、p99等等)
看完是否有些感覺?這就是我們日常工作中可能會關注的一些指標。在這里,我們給這些指標取個專業點兒的名字:“維度”,也就是觀測應用的某一個角度。一個應用存在多個被關注的指標,那么我們就從多個維度出發,去對它進行監控。天機鏡利用了java Metrics(一個開源的度量包https://dropwizard.github.io/metrics/3.1.0/)對監控行為做了幾個分類:a. 絕對值;b.計數;c.速率;d.時間分布;e.數值結果分布;基本上任何不同類型的度量需求都會被這五種度量類型滿足。下面可以簡單的列舉一些例子:
絕對值:隊列大小,Buff使用(基本上是一些size類的)
計數:GC次數、累計時間,出現403次數,返回錯誤error1的次數
速率:tps,qps,function1的每秒調用次數
時間分布:function1調用時間50%(75%,98%,99%,99.9%)都在多少秒以下,最大耗時,平均耗時
數值結果分布:function1的返回值50%(75%,98%,99%,99.9%)都在多少以下。
上面的這些實例性的描述,基本可以涵蓋80%的需求。實際上,我們在設計采集客戶端時,就是為了滿足這80%的需求。再這個前提下,保證常用api的default設定能夠在大部分情況下適用。
數據模型與查詢接口
數據模型的設計需要考慮功能與相應的存取效率,而查詢接口就要巧妙利用模型中的數據直觀多元的呈現給用戶。我們在考慮設計監控數據結構時參考了現實世界的破案現場,因為最初的設計動機就是為了快速定位系統出現的問題,實際上我們需要的就是:(人物,時間,地點,事件),再直白一點就是:(應用,時間戳,進程唯一標識符,維度及維度大小)。你可以回過頭去看上面OOM的例子。在視覺影像完全靠腦補的日子里,我們只能從黑白控制台中利用丑陋的命令行去查看系統日志。天機鏡出現以后,我們簡單的在界面上點擊幾下,他就會將當時的現場回放出來。下面是存儲表結構的細節:
appID: 應用的唯一標識 sceneID:場景ID,應用下面的唯一標識 timestamp:時間戳 location:匯報該指標所在的位置,可以是一個ip,也可以是一個ip+端口,也可以是用戶自定義的一種特定標識 dimValue:具體指標名稱,比如在負載場景下,具體指標就有:QPS,刷磁盤速率,Buffer大小等等 kpiValue:對應指標的值,可以是速率類型的,也可以是百分比類型的,也可以是個絕對值大小
查詢接口非常簡單,我們需要設定一個條件:時間區間,哪些維度,哪些進程(ip or ip+pid)。另外我們提供了多種展示方式,可以將相同的維度的不同曲線放在一張圖表(例如:負載均衡比較),也可以將一組ip的不同維度放在一張圖(消息系統流入流出的流量比較,命中與未命中數量的比較)。
采集客戶端設計
采集客戶端的設計決定了監控平台的易用性,使用者往往是業務開發人員,要用最小的成本換來最大的收益。所以在設計客戶端時我們從不同的角度考慮了其易用性:
1. 輕量化的客戶端:對於完成api層面的監控,我們首先要將采集客戶端植入應用之中,這里我們選擇在client端做輕量化的統計計算,並且開啟一個靜默線程每一分鍾把當前的計算結果發送到后端存儲,在網絡不通暢的情況下,客戶端感知不到異常的存在。同步監控統計結果太頻繁不僅會導致后端存儲壓力過大,也會影響用戶應用的性能,更重要的是,實時需求1分鍾足以。
2. 超簡單的API:用戶最希望的是寫一行代碼就完成了監控工作,而現實中我們也的確是這么做的。之所以能做到這一點,也正是因為我們梳理出80%的需求,而另外20%個性需求才需要調用較為復雜的API,並且有些通用監控室無需設置的,比如JVM相關的各種監控。
所以對於監控數據的收集,我們的定位是:歸檔時間長,允許丟失,近實時,統計量豐富。可能用一個詞匯描述監控數據比較合適:“可視化應用日志”。
服務端設計
對於簡單表結構存儲大量數據的場景,Hbase是我們的絕佳選擇。為了滿足天機鏡的查詢需求,我們在Hbase集群上安裝了Phoenix插件。Phoenix支持了類SQL語言,很容易與前端界面集成在一起,另外對於接收服務器,我們簡單的使用nginx+webserver的方式。對於更大的並發量,可以在接收服務器做一些batch以及throttle。接收服務器的好處還有一個就是解耦了采集端與存儲層,天機鏡除了支持Hbase存儲之外,還支持了mysql存儲。另外對於不同的數據源,接收服務器還可以支持采集jmx監控數據。
圖3 天機鏡整體架構圖
豈止於監控,數據總是有用的。目前我們對數據平台的基礎服務層做了一定的封裝,內置了很多通用指標的監控,這樣我們可以對所有平台的使用者的應用做出大致的資源占用量監控,比如消息系統的流量貢獻、消費與生產消息量的核對、請求量統計、緩存命中率、數據掃描量等等。天機鏡開放了數據訪問接口,用戶可以定制報表,平台管理員可以生成消費資源報表。另外,利用其近實時(一分鍾內)的特性做短信和郵件的報警等等。
3. 一些結論與建議
總體而言,天機鏡的工作是把應用的運行日志圖形化展現,並且可以根據任何時間以多元方式對比呈現,大大化簡了排查問題的難度,同時通過報表也能讓我們更直觀的了解程序,預警功能避免一些問題的發生。天機鏡像是一種刻畫數據平台生態鏈各環節狀態的數據引擎,當然,這需要精心設計出一個更好的交互式UI或者報表。
客戶端
需求的梳理,最簡單的api滿足最大眾的需求,如果想兼顧,那么必然會讓api更加復雜難用;
不需要刻意追求數據的高實時性,增大80%的成本卻提高了1%的收益這是得不償失的;
既然是“可視化日志”,那么就允許丟失,同上;
靜默,不要因為監控影響了自己的應用運行;
服務端
做好解耦,這樣無論你因為量級升級系統,還是因為功能升級系統都有很大的好處;
中間件的數據處理策略會讓你的基礎服務更加穩定、高效;
存儲端
我們在使用Hbase時遇到的最大問題在於刪除數據后會導致一些IO風暴,另外在Phoenix0.4.0存在了跑死cpu的情況(0.4.2已經解決)。對於這些情況我們的解決方案是,讓表在時間上分表。換而言之就是讓table像日志文件一樣按照時間rolling,這樣的好處是刪除老數據永遠都不會出現IO風暴,因為直接drop的表更當前寫入的表無關。單表的數據量也會因此大大減少,查詢會非常高效。但缺點就是查詢時需要做一些簡要的時間區間判斷,在跨表查詢時會十分繁瑣,需要做兩個sql的結果進行合並。