裴歐亞,康慕寧,張 磊
(西北工業大學 計算機學院,陜西 西安 710072)
隨著Linux操作系統在大型服務器上的廣泛應用,對系統的性能提出了更高的要求。因此Linux系統開發人員希望通過對Linux系統進行性能測試,定位系統瓶頸,分析引起性能問題的原因。系統的性能不能通過單一指標來判定,必須通過系統的整體性(綜合指標)來判定。Linux作為全球最廣泛使用的開源操作系統,其超高的性價比,決定了對此內核的可視化性能分析研究具有重要的學術意義及深遠的教育意義。
可視化其實質是利用計算機的圖形圖像技術,把各種數據信息轉換成合適的圖形圖像在屏幕上表示出來。這一過程涉及到圖形學、和人機交互等領域知識。基于SystemTap的Linux服務器性能分析系統通過SystemTap,在Linux內核的合適位置添加探針,當啟動檢測時,以事件追蹤機制實時進行數據的收集、解析,最終以可視化的界面呈現給用戶。用戶可以通過可視化界面直觀的對系統的資源利用率及運行狀況進行性能分析和優化。
針對為滿足Linux服務器性能分析的需求,結合SystemTap及 “事件追蹤機制”等技術方式,經過分析得到Linux性能數據共分為以下3個部分:進程/線程的實時運行狀態;進程間的通信狀況;以及對系統資源的占用狀況。
要想完成以上性能數據的收集、分析及可視化等功能,需要做好以下幾個方面。首先服務器端應能實時收集性能數據,并且能確保將收集到的性能數據傳回客戶端;其次客戶端能正確解析服務器段傳回的性能數據,即將數據轉換成可視化數據;最后可視化模塊能將最終結果呈現給用戶。
本系統在軟件架構上基于C/S結構,server端負責接收命令、收集數據及發送數據,client端負責控制、解析數據及顯示數據,很好的滿足了用戶提出的“盡量減小對服務器性能影響”的需求。
C/S(Client/Server)模式即客戶端服務器端架構,它可以采用任何通信協議,客戶端包含一個或多個在用戶的電腦上運行的程序,客戶端向服務器端發送請求命令,由服務器處理響應并將信息返還給客戶端,再由客戶端處理服務器的返回信息并將處理結果顯示給用戶。雖然B/S架構是對C/S架構的改進,但是C/S相較于B/S,其具有的響應速度快,對服務器性能影響較輕的特性,決定了本系統必須使用C/S架構。
該性能分析系統的系統結構圖如圖1所示,在對目標服務器進行測量時,首先目標服務器必須開啟Server端服務;接著Client端向Server端發送開始監測命令,Serevr端收到開始命令、啟動監測并記錄數據;然后Client端向Server端發送終了監測命令,Server端收到終了命令、停止監測并將數據傳回Client端;最后Client端先調用解析模塊將Server端傳回的數據解析,然后調用可視化模塊將解析的結果以圖形化方式顯示給用戶。

圖1 系統結構圖Fig.1 Structure diagram of performance analysis system
該性能分析系統軟件采用C/S架構,客戶端功能:向服務器端發送控制命令、接受服務器端數據、數據解析及數據可視化功能,服務器端功能:接受客戶端命令后回傳性能數據和收集性能數據。為了日后的更新、維護和拓展,在設計過程中采用模塊化的思想,因此將客戶端劃分為通信模塊,數據解析模塊,數據顯示模塊。服務器端劃分為通信模塊,數據收集模塊。系統軟件設計的結構圖如圖2所示。

圖2 系統軟件設計結構圖Fig.2 diagram of the software analysis system
在軟件設計中,數據收集模塊主要用來實現對Linux服務器性能數據的收集;服務器端的通信模塊主要用來接受客戶端發送來的命令,通過該模塊可以控制數據收集模塊的啟用開關,并且能將收集到的性能數據傳回客戶端;客戶端的通信模塊主要用來向服務器端發送命令以及接受服務器端傳回的性能數據;數據解析模塊主要用來將性能數據解析成可視化的數據;數據顯示模塊主要用來將可視化的結果以圖形化界面方式呈現給用戶。
為了收集linux實時的運行數據,必須借助于System Tap[1-6],在Linux kernel源代碼的關鍵之處加上探針,并為所加探針新規處理函數(保存獲取的內核數據)。一旦探針被觸發,被觸發探針的處理函數立即保存獲取的內核數據。
例如:創建進程(sched_process_fork)處添加探針及探針處理函數如下:

實現數據收集模塊的難點有以下3點:
第一點:確定探針添加的位置。探針添加的位置決定能獲取何種類型的linux內核數據。此外SystemTap的探針處理是以中斷方式處理的,而linux內核在某些代碼處不允許產生中斷(中斷會導致系統宕機等問題),再加上SystemTap理論上可以在linux內核任意位置添加探針,所以添加探針的操作必須小心謹慎。因此需要開發人員必須熟悉linux內核某個功能或全部功能的源代碼及處理邏輯流程。
第二點:探針處理函數的高并發導致的“寫競爭”。每一個探針都關聯一個寫內存的處理函數。在負載很重的服務器上,同一個探針不間斷被觸發,或多個探針同時被觸發,都會導致多個處理函數競爭同一個內存塊。因此必須為內存塊填加寫互斥鎖,實現內存塊的互斥訪問。本系統為實現寫內存互斥,定義了一個全局的靜態變量(變更靜態變量值的操作是原子操作)。每一個處理函數寫內存之前都要先判斷靜態變量的值。如果為TRUE則可繼續進行后續操作;否則,將阻塞。
第三點:長時間測量。經過實驗:單臺小型服務器在高負荷工作時,少量探針(hooks)每秒產生的需要保存的數據就高達40M,因此只能將收集的數據寫入磁盤保存。為了避免頻繁寫磁盤對服務器正常I/O操作產生影響,同時加快寫磁盤的速率,盡可能避免因磁盤寫速率低造成的數據丟失。本系統采用如下設計:
在內存中申請3塊大小為64M (可由用戶手動設置,默認最小 64M)的內存空間,編號為 BufferNo0,BufferNo1,BufferNo2。這3塊內存按編號從小到大循環使用。只有當當前的內存空間為空并且前一塊內存空間寫滿的情況下,才能向當前的內存空間寫數據。每一塊內存都有互斥鎖,保證同時只有一個探針的處理函數向可寫內存塊寫數據。每當一塊空間寫滿,立刻將該寫滿的內存塊中的數據轉移至磁盤,同時清空該內存塊,為接下來需要保存的數據準備空間。
從服務器端傳回的性能數據是以二進制的形式保存的,用戶幾乎不可能快速通過查閱二進制信息來分析服務器的狀況。因此必須將二進制形式的數據解析成方便用戶查閱及可視化模塊使用的數據格式。
長時間的收集使得最終收集的數據量高達數G(目前最大支持4G),因此解析大數據的性能成了本性能分析系統的瓶頸。
為了提升解析數據的效率,最終選取了Windows操作系統提供的內存文件映射技術。內存映射文件技術是由一個內存映射文件是由一個文件到一塊內存的映射,使進程虛擬地址空間的某個區域與磁盤上某個文件的部分或全部內容建立映射。建立映射后,通過該映射區域可以直接對被映射的磁盤文件進行訪問,而不必執行文件的I/O操作,也無需對文件內容進行緩沖處理,就好像整個被映射的文件都加載到了內存一樣。
運行內存映射主要有以下幾個步驟:
1)用函數CreateFile(),以適當的方式創建或打開一個文件核心對象;2)將函數CreateFile()返回的文件句柄作為參數,調用函數CreateFileMapping(),創建一個內存文件映射對象;3)調用函數MapViewOfFile()將整個文件的部分區域或者全部映射到內存;4)用函數MapViewOfFile()返回的指針來讀寫文件;5)調用函數UnMapViewOfFile()來解除文件映射;6)調用函數 CloseHandle()來關閉內存映射文件;7)調用函數CloseHandle()來關閉文件核心對象[7]。
數據顯示模塊主要是將數據解析模塊生成的可視化數據以圖形界面的方式呈現給用戶。為了消除重繪過程中產生的閃屏問題,采用了雙緩沖機制來繪制圖像[8]。
可視化界面沿著水平時間軸 (單位/s)真實地還原了linux服務器運行時,進程調度、磁盤調度、系統資源(cpu、disk等)的占用率。
可視化界面[9]截圖如圖3所示。

圖3 可視化界面截圖Fig.3 The screenshot of visualization interface
圖3的左側是Linux運行時所有進程的列表,包括進程名、進程ID及線程ID。右側就是進程動作狀況表示區域,顯示所有進程/線程實時運行狀況。進程/線程對Cpu和磁盤的使用狀況只分為兩種狀態:執行中和等待即空閑狀態,分別標記不同的顏色進行區分。當不同進程進行通信時,以不同的顏色進行區分通信的方式,如信號、PIPE(管道)、NPIPE(無名管道)、MESSAGE等方式。
圖3中顯示了進程號和線程號均是4389的進程Xorg與進程號和線程號均是4727的進程gnome-terminal之間通信的動作。
某一產品軟件,客戶端和服務器端通信開銷突然從0.5 s增加至4 s。由于邏輯復雜,開發人員短時間內無法分析出問題原因,通過使用本系統,使內核狀況可視化,只用一個小時就將問題點明確,快速解決了該問題。
通過可視化測量結果,進行詳細分析,發現一個問題見圖4中第一幅圖虛線框列出的問題:1。

圖4 可視化性能分析實例Fig.4 The example of Visualization performance analysis
問題:CPU等待/空閑區間過多
根據問題應采取以下措施進行改善:
1)CPU等待/空閑區間的原因檢討;
2)減少進程間的通信次數;
通過以上兩點對代碼進行改善,再次運行后,對比發現:改善前需要9.75 s的處理時間,改善后只需要1.95 s(約1/5)。
注:上下兩幅圖倍率,區間相同 (時間間隔6 s)
本軟件系統采用模塊化設計,提高了系統的可擴展性和可維護性,便于二次開發。該軟件系統采用了友好的界面設計,目前已交付某大型跨國IT企業使用,主要用于分析該企業大中型服務器的性能。實際應用情況表明,該系統顯著地縮短了解決服務器性能問題所需的時間,同時該系統還具有操作簡單,穩定可靠、人機交互良好等特點,達到了要求。
但是本系統還有以下不足:
1)在Linux操作系統中添加的‘探針’數量較少,導致獲取的性能數據不足。
2)Linux服務器將內存數據轉移至磁盤過程中,由于探針產生的數據量過大,會導致部分需要收集的數據丟失。
3)可視化界面對性能數據的顯示粒度略顯粗糙。
因此,后期將對以上不足進行仔細分析并逐一解決,進一步完善本文所描述的性能分析系統。
[1]李云華.Linux內核調試新秀System Tap[R].程序員,2010,(3):127-127.
[2]Frank Ch.Eigler.Systemtap tutorial[EB/OL].(2013)[2013-08-20].http://www.sourceware.org/systemtap/tutorial.pdf
[3]SystemTap Language Reference[EB/OL].(2013)[2013-08-20].http://www.sourceware.org/systemtap/langref.pdf
[4]薛偉偉.軟件性能測試和分析方法的研究與應用 [D].西安:西北工業大學,2013.
[5]謝雨辰.基于SystemTap的Kprobes與Relayfs的開發[D].吉林:吉林大學,2007.
[6]Prasad V,Cohen W,Eigler F,etal.Locating system problems using dynamic instrumentation[C]//Linux Symposium,2005:49-64.
[7]馬禮,李敬喆,葛根焰,等.一種基于多核環境的海量數據快速讀取方法[J].計算機研究與發展,2011(48):63-67.MA Li,LI Jing-zhe,GE Gen-yan,et al.Quick-Read means ofmass data based on multi-core environment[J].Journal of Computer Research and Development,2011(48):63-67.
[8]明日科技,孫秀梅,王雪,等.Visaul C++典型模塊與項目實戰大全[M].北京:電子工業出版社,2012.
[9]王卉,趙政文,齊萬華.基于Windows運行過程可視化的軟件性能分析[J].微處理機,2013(1):45-48.WANG Hui,ZHAO Zheng-wen,QI Wan-hua.Software performance analysis of visualized software based on windows operating[J].Microprocessors,2013(1):45-48.