應對日產140億條監控數據!京東監控系統戰技全解

ZanDykes 7年前發布 | 11K 次閱讀 系統監控 軟件架構

大家好,我是來自京東商城-基礎平臺-集群技術部的李旦,目前主要參與負責京東統一監控平臺的設計研發,以及彈性集群的建設工作。這次分享的主題是:大規模集群(物理機&容器)環境下,監控系統的設計與實踐經驗。

主題簡介:

一、MDC架構設計詳解
二、海量監控實踐

這次分享主要包含兩部分內容,第一是對京東監控系統MDC的架構設計做一個簡單介紹,第二是分享一下我們在實踐過程中遇到的問題以及總結的經驗。

MDC架構設計詳解

先簡單介紹一下MDC系統,MDC系統由京東自主研發,對下針對物理機、容器的基礎資源使用情況,以及業務常用組件的性能實施監控;對上為用戶提供高效的監控數據服務和告警服務。

系統的總體架構很簡單,功能劃分得也很清晰,將采集與任務管理解耦。任務可以無狀態地在Agent間遷移,方便橫向擴展。

主要分為三部分:

  1. Dashboard,Web-UI。

  2. Controller,控制器。對內負責采集資源的管理和采集任務的調度,對外提供豐富的數據獲取,報表生成接口。

  3. Agent,采集器。實際的數據采集,告警執行者。

另外,我們在Controller上掛了一層VIP,把Controller服務整體封裝成統一入口,可以方便采集服務(Agent)發現的實現和對外接口調用。

這里的Agent是一個邏輯上的概念,實際包含采集、告警、數據處理等多個模塊。

這是Agent內部的架構,這里列出了主要的四個部件,它們之間通過消息隊列相互通信。

按消息流向來看,Central負責采集任務的處理,并把任務下發到Sniper。

Sniper功能劃分得很簡單,它只用來做數據采集,沒有摻雜其他業務邏輯,這樣能在一定程度上保證采集效率不受干擾。

Sniper在采集完成后,通過消息隊列將采集到的數據返回到Central中,Central在對數據處理完成后,將其發送到Filter和Collector的隊列中。

Filter負責過濾數據,進行告警。Collector進行數據處理聚合,然后將數據放入緩存,存儲。

采集Sniper,用插件的方式實現不同采集類型的靈活加載。

目前通過SNMP+IPMI,采集物理機的資源使用情況和一些硬件信息。

容器采集的實現,是在宿主機上部署DockerPull采集代理,對外暴露RESTful Api,Sniper通過RESTful Api通用插件獲取其數據。

告警設置包含三部分,用戶組、告警組和資源組。支持多級別、多閾值、多間隔、多種通知途徑的規則設置,最大程度的方便用戶訂制告警。

海量監控實踐

從前面的運營數據可以看出,MDC系統承載監控目標的量還是很大的,而且增速較快。所以在設計之初,我們就確定了幾個設計目標:高性能、低開銷、高擴展、高可用。接下來分享我們在這些方面的一些實踐。

MDC的數據采集采用了“pull”的模式:通過SNMP和IPMI協議獲取物理機的監控信息,通過在目標節點上部署Agent,獲取容器的監控信息。

實踐中遇到的性能問題,只要集中在物理機的數據采集上:

首先是SNMP采集的優化。由于我們開發用的Python語言,在做SNMP處理時,自然而然地找到了Pysnmp這個pure-Python的SNMP實現。但是在測試時發現,Pysnmp這個庫可能是由于Python本身并發限制的問題,效率并不能滿足我們的要求。解決思路就是底層采集使用C或者其他更高效的實現來做,我們對比選擇了Netsnmp這個C的SNMP實現。通過測試,發現Netsnmp在并發處理時,效率遠高于Pysnmp。

其次是IPMI采集的優化。IPMI可能是由于協議本身或者BMC芯片采集效率的問題(具體不明),導致數據返回緩慢(分鐘級)。IPMI的采集效率問題無法從源頭解決,所以我們在實現中做了一些實時性方面的妥協,解決思路就是在IPMI的采集模塊中加入緩存,緩存會被定時刷新,同時接受到IPMI采集請求時,會立即返回緩存中的數據。

然后是慢采集的優化。由于網絡,目標機性能等原因,會出現一些采集較慢的目標機。這些慢采集我們做了兩層處理,首先是在采集任務內,將慢采集做自適應降級處理,這樣既能保證慢采集目標的數據可用性,又不會影響采集任務內其他目標機的采集。其次在采集任務間,如果慢采集影響了任務的整體性能,會通過將任務做拆分,遷移處理來保證任務整體的采集效率。

低開銷是我們監控系統設計的另外一個原則,就是盡量降低監控系統本身對生產環境資源的損耗。我們把各個組件(Central、Sniper、Filter、Collector)和它們之間交互所需要的消息中間件(RabbitMQ)打包成一個邏輯上的Agent部署在一臺物理機或者容器上。

這樣做有兩個好處,一個是避免了大規模集群環境下,RabbitMQ的性能瓶頸問題。另外一個,除了采集和存儲時產生的必要的網絡流量,組件之間的數據交互都在機器內部進行,不會流向機器外部,對網絡做成額外壓力。

主要從三個層面做了高可用的處理:進程存活、服務存活、采集業務存活:

  1. 進程存活,保證相關進程存活,進程掛掉時自動重啟;

  2. 服務存活,保證服務整體可用,部分服務掛掉不影響整體可用行;

  3. 采集業務存活,保證采集任務不丟失。

我們把Controller、Agent打包部署在Docker容器中,依托于彈性集群平臺,實現自動擴容縮容。

Agent定期向Controller上報自身性能數據,Controller根據設定的閾值,對Agent總體進行統籌規劃,調用彈性平臺的接口實現擴容縮容。

Q&A

Q1: 如果有新增容器,Agent是手動部署上嗎?每個容器上應該都有對應的線上業務,這個Agent是怎么做版本更新的呢?

A1: 有容器的發現機制,可以把容器信息自動導入系統中, 然后生成新的采集任務,或者合并到其他采集任務中,由空閑Agent接管。Agent更新我們用Ansible做了一套獨立的升級工具。

Q2: 消息中間件RabbitMQ有沒有進行二次開發?小弟最近遇到一個問題,消費端的ack如果在傳輸過程中丟失,服務就不再向此消費者發送待消費消息,不知道有沒有好的方案解決這個問題?

A2: RabbitMQ我們用的官方原版,沒有做二次開發,因為之前使用中也遇到過一些問題。所以我們把Rabbit的兩端都圈定在同一機器中,這樣能大概率避免一些問題。不過這種做法可能只適用于我們的應用場景,沒有普適性。

 

來自:http://dbaplus.cn/news-21-984-1.html

 

 本文由用戶 ZanDykes 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!