1. 程式人生 > >適合生產環境的效能監控類庫 之 大資料篇

適合生產環境的效能監控類庫 之 大資料篇

上期回顧

上次介紹了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的介紹文章也早就有不少了,我就不說太多安裝使用細節了。

//本文完