NanoProfiler - 適合生產環境的性能監控類庫 之 大數據篇


上期回顧

上一期:NanoProfiler - 適合生產環境的性能監控類庫 之 基本功能篇

上次介紹了NanoProfiler的基本功能,提到,NanoProfiler實現了MiniProfiler欠缺的多線程和異步代碼的支持,並且,由於采用不同的內部數據結構,NanoProfiler擁有更高的執行效率,而且占用極少的系統資源,因此,是適合在生產環境下使用的性能監控類庫。並且,我們也提到了,NanoProfiler設計理念的另一大不同,即面向大數據分析。

這一期,我重點介紹一下NanoProfiler之大數據分析理念。

面向大數據分析的數據結構

上一期,我們曾經簡單介紹了,NanoProfiler和MiniProfiler相比的,由於采用了不同的數據存儲結構,因而具有更高的執行效率。這一節,首先,詳細介紹一下NanoProfiler的數據存儲結構。

首先,我們先來舉一個簡單的例子。假設我們有個對APP1的Web頁面請求R,請求R的執行過程中,我們有以下幾個Step:R-step-1, R-step-2,R-step-2的執行過程中,調用了APP2的一個WCF服務方法W.而W的執行過程中,又有以下幾個Step:W-step-1, W-step-2。

如果使用MiniProfiler進行性能監控,R這個請求,可以得到類似下面的一整個樹形結構的數據:

R (start, duration)
|
- R-step-1 (start, duration)
|
- R-step-2 (start, duration)
  |
  - W (start, duration)
    |
    - W-step-1 (start, duration)
    |
    - W-step-2 (start, duration)

start和duration表示,每個步驟相對整個請求開始的開始時間和執行時間。

MiniProfiler運行時,在內存中對一個邏輯請求,維護這樣一個樹形結構的數據,即使執行過程中有WCF調用,它也會通過WCF的EndpointBehavior和MessageInspector,將在APP2中執行的WCF調用內部的性能監控數據,返回並且合並到APP1的R請求這棵樹結構數據。如果,當前請求包含一些前端的性能監控步驟,所有前端性能監控數據,也會實時保存到同一個內存中的數據結構中。如果要持久化,也會將整棵樹,保存為一個JSON。這樣做,雖然方便查看整個請求整體的性能數據,但是,不可避免的有以下一些問題:

  • 因為要在內存中維護這棵樹,如果有並行的步驟,運行時,不得不加鎖,因而,執行效率較差;
  • 跨應用(比如例子中APP1的請求調用了APP2的WCF)的調用,需要被調用方,將監控數據返回到調用方,增加了不必要的數據傳輸,因而,影響執行效率,也占用了不必要的內存(更何況,如果這個WCF服務是One-Way的呢?);
  • 如果同一個邏輯請求包含相關的多個子請求(比如,包含多個前端的AJAX請求和后端的WCF調用),R請求至少要等待所有這些子請求的性能監控數據全都返回並且合並之后,才能通知R請求的調用方R請求執行完畢,但是,這些子請求如果不是為了性能監控,R請求本身的執行邏輯,其實本來未必有依賴,因此,這樣的機制,既導致了額外的內存開銷,還導致了對R請求本身的執行時間的影響;
  • 將整個邏輯請求的性能監控數據整體保存為一個JSON,雖然方便后期查看這個請求本身的數據,但是,由於這個整體的樹結構嵌套層次數量不可控,因此,不利於后期的數據分析,比如:如果我想分析某一天,上例中W這個WCF服務總的執行次數,平均執行時間等,將不得不需要解析和索引每一個嵌套層次的JSON,很難保證執行效率;

那么,NanoProfiler是怎么存儲性能監控數據的呢?

假設還是上面的例子,如果使用NanoProfiler代替MiniProfiler,在在APP1的內存中,請求R的性能監控數據結構大概是下面這樣的:

R (type=web, start, duration, tags=request_token_of_R) :{
  Steps: [
    R-step-1 (type=step, parent=R, start, duration),
    R-step-2 (type=step, parent=R, start, duration)
  ],
  Customs: [
    W-client (type=wcf_call, parent=R-step-2, start, duration)
  ]
}

同時,在APP2的內存中,有另一個WCF服務調用W的性能監控的數據結構:

W-server (type=wcf_server, start, duration, tags=request_token_of_R) : {
  Steps: [
    W-step-1 (type=step, parent=W-server, start, duration),
    W-step-2 (type=step, parent=W-server, start, duration)
  ],
  Customs: [
  ]
}

看出區別了嗎?

  • 首先,NanoProfiler的數據結構不是一棵樹,而是一些平面的數組,因而,即使要維護一棵樹的父子關系(即使在有並行步驟的情況下),也無需關心樹結構的層次嵌套,只需要將每個步驟的監控結果,添加到平面數組,執行效率顯然更高;

  • R和W雖然屬於同一個邏輯請求,但是,他們分別在自己的APP里維護自己的性能監控數據,僅通過tags的方式進行關聯,好處是什么?很明顯,R執行結束,無論子請求是不是One-Way的,都不需要等待相關的其他子請求完成,並且返回性能監控數據就能通知調用端執行完畢,存放監控數據的內存也能立即釋放,所以,即使開啟了性能監控,也基本不會影響R請求的執行時間和整體的內存消耗;

  • NanoProfiler,並不將每個請求的監控數據整體保存為一個對象,而是會將每一個步驟,保存為一個對象,例如,對上面的例子,我們一共會得到下面這些事件數據:

    • R (type=web, start, duration, tags=request_token_of_R)
    • R-step-1 (type=step, parent=R, start, duration)
    • R-step-2 (type=step, parent=R, start, duration)
    • W-client (type=wcf_client, parent=R-step-2, start, duration)
    • W-server (type=wcf_server, start, duration, tags=request_token_of_R)
    • W-step-1 (type=step, parent=W-server, start, duration)
    • W-step-2 (type=step, parent=W-server, start, duration)

上面這樣的存儲結構有什么好處呢?

  • 首先,沒有嵌套層次,非常容易被解析和存儲;
  • 即使,對同一個邏輯請求的性能監控,被拆分成多個事件,但是,他們之間可以方便的通過每個事件的tags和parent屬性的值進行關聯和追蹤;
  • 方便只對某一種type的監控數據進行宏觀的大數據分析,比如,我要分析一天之內W這個WCF服務的調用次數和執行的平均時間非常容易;
  • 由於避免了不同子請求的性能監控數據之間的直接耦合,而通過tags進行關聯,方便和其他異構log系統的數據,進行大數據整合,例如,對這個請求的微觀和宏觀性能分析,可以包含跨應用,跨服務器甚至集群的異構的異常日志,前端日志,服務器日志等等(只要,這些相關日志之間能夠通過相同的request_token進行關聯),而不用像MiniProfiler那樣,只局限於單個請求的數據,只局限於MiniProfiler能支持的類庫產生的監控數據的整合,這就大大提高了大數據分析的靈活性;
  • 事實上,在NanoProfiler中,對需要監控性能的每一個步驟,無論是代碼步驟,還是DB請求,WCF請求,都可以指定0到多個tag,請求的token作為tag只是一種應用方式,我們完全可以對某個步驟,指定其他各種目的(無論是業務的還是非業務)的tags,實現各種維度的微觀和宏觀的大數據分析;

面向大數據分析的數據存儲

數據結構Ready了,下面是怎么存儲的問題。NanoProfiler的性能監控數據,由上面舉例的相同結構,但類型可能不同的平面事件數據組成。我們假設,平均每一個邏輯頁面請求會產生20個event,如果,某個APP一天有500萬頁面請求(包含各種服務調用,AJAX請求等等),就會有1億個event。這個數據誇張嗎?對一個稍大一點互聯網應用來說,一點也不誇張。所以,這里的數據,必然有那么點“大”的。這還是只一個APP,如果,有10個100個APP呢?

對於超大量的類日志數據,傳統的文件系統,或者關系型數據庫,很可能已經不能很好的勝任了。不僅僅讀寫性能未必能達到要求,數據的維護也會成為大問題。

所以,我們需要特別適合類日志數據存儲的數據存儲方案。很幸運的,很多走在前面的大數據公司,已經鋪了不少路,我們現在有Cassandra,有HBase這些本身就是類日志存儲的NOSQL數據庫,非常適合類日志的超大量密集寫操作的數據存儲。

以Cassandra為例,早在3年前,就已經可以達到每秒超過百萬次的寫操作,這里也有一個中文的翻譯。Netflix當時使用了288個節點達到的每秒百萬寫,而最近Datastax公司的測試,已經能達到1000個Cassandra節點的線型性能擴展了,可以簡單計算,即使三年后,Cassandra單個節點的寫並發能力沒有增加,支持每秒幾百萬的寫操作也是很輕松的事情。

大數據分析工具

說起大數據分析,大家一定首先想到Hadoop。但是,如果各位做大數據分析,卻還沒嘗試過elasticsearch和kibana,那真的有點out了。

園子里關於kibana的介紹文章也早就有不少了,我就不說太多安裝使用細節了。

//本文完


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM