http://www.cnblogs.com/LBSer/p/3390852.html
最近單位需要做自己的分散式監控系統,因此看了一些資料,其中就有google的分散式追蹤系統dapper的論文:http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/zh-CN//pubs/archive/36356.pdf,結合自己的理解描述下這篇論文。
一、引子:
使用者輸入關鍵字後只要敲個Enter鍵就能返回搜尋結果(圖1a),這樣一個簡單的過程可能涉及到上千個服務,可能需要上千個伺服器協作完成。如圖1b所示,user發了RequestX請求到達A,A通過rpc(遠端過程呼叫,如thrift)呼叫B以及C,而C又需要通過rpc呼叫D以及E等等。
對user的一次請求,他遲遲未收到響應ReplyX,或者響應時間很慢,我們需要確認效能到底消耗在哪個環節,這個時候我們該怎麼辦呢?自然是分析我們的日誌。
我們每個服務都會有請求日誌,請求日誌記錄著一次呼叫所花費的時間,比如對A來說,記錄著呼叫B所花費的時間以及呼叫C所花費的時間,同理C的請求日誌記錄著呼叫D以及E所花費的時間。對於網際網路應用來說,各個服務比如B,同一時刻可能有成百上千次請求記錄。
這種日誌有個致命缺點---沒有將這些記錄與特定的請求關聯一起。對於user的一條特定的請求RequestX,我們不知道B日誌中哪條記錄與之對應,也不知道C日誌中哪條記錄與之對應。。。總而言之,我們不能很具體的分析user的一次請求響應緩慢到底消耗在哪個環節。
二、 如何將各個服務日誌的每一條記錄與特定的請求關聯在一起呢?
當前學術界和工業界有兩種方法:
1)黑盒方法(black box)
日誌還是一樣的記錄,只是通過機器學習的方法來關聯記錄與特定的請求。以一條特定請求RequestX為變數,通過黑盒(也就是機器學習的模型,比如迴歸分析)從A的日誌中找出一條記錄與之對應,同理可以找出B、C、D、E等等的相關記錄。
黑盒方法的優勢就是不需要改變現有日誌記錄方法,但是缺點很明顯,機器學習的精度往往不高,實際使用中效果不好。
2)基於註釋的方案
利用應用程式或中介軟體給每條記錄一個全域性標誌符,藉此將一串請求關聯起來。比如對RequestX來說,賦予一個標誌符1000,後續相關各個服務都會將識別符號1000與記錄一起打在日誌裡。這種方法的優勢就是比較精確,目前google、twitter、淘寶等都採用這種方式。下面介紹google的分散式追蹤系統解決方案---dapper。
三、dapper的設計目標:
1)低消耗
dapper本質是用來發現效能消耗問題,如果dapper本身很消耗效能,沒人願意使用,因此低消耗是必須的,dapper使用一系列創新方法確保低消耗,比如使用取樣方法。
2)應用級透明
應用級透明的意思是程式設計師可以不需要在自己的程式碼中嵌入dapper相關的程式碼就能達到分散式追蹤日誌記錄的目的。每一個工程師都希望自己的程式碼是純粹的,如果需要嵌入dapper相關程式碼,那麼既影響程式碼維護,又影響bug定位。
3)擴充套件性好
對於一個快速發展的網際網路公司而言,使用者規模快速增長導致著服務以及機器數量越來越多,因此dapper需要適應相應的發展,擴充套件性要好。
四、dapper的幾個關鍵點:
1)dapper日誌記錄的格式是怎樣的呢?
dapper用span來表示一個服務呼叫開始和結束的時間,也就是時間區間(圖2對應著圖1b的呼叫圖)。dapper記錄了span的名稱以及每個span的ID和父ID,如果一個span沒有父ID被稱之為root span。所有的span都掛在一個特定得追蹤上,共用一個跟蹤ID,這些ID用全域性64位整數標示,也就是圖2的traceID。
2)如何實現應用級透明?
在google的環境中,所有的應用程式使用相同的執行緒模型、控制流和RPC系統,既然不能讓工程師寫程式碼記錄日誌,那麼就只能讓這些執行緒模型、控制流和RPC系統來自動幫助工程師記錄日誌了。
舉個例子,幾乎所有的google程式間通訊是建立在一個用C++和JAVA開發的RPC框架上,dapper把跟蹤植入這個框架,span的ID和跟蹤的ID會從客戶端傳送到服務端,這樣工程師也就不需要關心。
3)dapper跟蹤收集的流程
如圖3所示,分為3個階段:a)各個服務將span資料寫到本機日誌上;b)dapper守護程式進行拉取,將資料讀到dapper收集器裡;c)dapper收集器將結果寫到bigtable中,一次跟蹤被記錄為一行。
4)如何儘可能降低開銷?
作為一個分散式追蹤系統,dapper希望儘可能降低效能開銷。如果對每一次的請求都進行追蹤收集,開銷還是有點大的。一個比較好的方式是通過統計取樣的方法,抽樣追蹤一些請求,從而達到效能開銷與精度的折中。
dapper的第一個版本設定了一個統一的取樣率1/1024,也就是1024個請求才追蹤一次。後來發現對一些高吞吐的服務來說是可以的,比如每秒幾十萬的請求,但是對一些低吞吐量的服務,比如每秒幾十個請求的服務,如果取樣率設定為1/1024,很多效能問題可能不會被追蹤到。因此在第二版本dapper提供了自適應的取樣率,在低吞吐量時候提高取樣率,在高吞吐量時降低取樣率。
上面的取樣是在第一個階段,此外在收集器將span資料寫到bigtable時,還可以使用第二次取樣,即不一定都將資料寫入到bigtable中。
五、dapper的使用
1)監測新服務部署效能情況
對一個新服務,往往需要經過一段時間的觀察,這時候可以使用dapper進行監測,從而發現存在的效能的問題;
2)推斷服務間的依存關係
通過使用dapper,可以很清晰的表明一個服務依賴了哪些服務,以及一個服務影響到哪些服務,這樣能促使我們在上線的時候能及時通知下游服務監控者重點觀察。
...)
六、dapper的不足
1)某些時候緩衝一些請求,然後一次性操作會比較高效,比如I/O請求等。各個請求都有traceID,但是聚集之後只有一個請求,因此只能選擇一個traceID用於傳遞到聚集請求,這時追蹤會中斷。
2)dapper可能找出某個環節慢了,但不一定能找出根源。比如一個請求慢可能不是它自身慢,而可能它在訊息佇列中比較靠後。
...)