基於虛擬機器並使用Vagrant(譯註:Vagrant用於建立和部署自動化虛擬化開發環境)開發環境主要瓶頸是檔案系統的效能。各平臺的CPU區別是很小的,甚至可以忽略不計,而且RAM只有在很多虛擬機器(譯註:指同一臺物理機上的虛擬機器)都活躍時才會成為效能瓶頸。昨天我花了大部分時間測試並分析了通用的檔案系統機制,現在把我結果分享給大家。
我將以對結果的分析開始,因為這是絕大部分人最感興趣的部分。其他諸如具體測試方法、使用的軟體、我所得到結果的原始資料等可以在分析的後面看到。
在下面呈現的每一個圖表中,我們以不同的方式測試讀寫一個檔案。對於每一個圖表,寫入檔案總大小是固定的。Y軸是以KB/s為單位的吞吐率,X軸是“記錄大小”或者一次性被讀/寫的大塊資料大小,以KB為單位。
不同的測試環境如下:本地、VirtualBox本地、VMware本地、VirtualBox共享資料夾(vboxsf)、VMware共享資料夾(vmhgfs)、NFS。”本地“是指用測試環境中自己的檔案系統。”本地“是在宿主機器上,” VirtualBox本地“是在VirtualBox虛擬機器跟裝置上,諸如此類。NFS只在VirtualBox上進行測試,因為VirtualBox和VMware的效能特點應該很相近。
對於所有圖示,吞吐率(Y軸)越高越好。
小檔案的順序讀取
首先,是一個對64KB檔案的序列讀取操作,測試了讀取各種記錄大小。在真實環境中對小檔案進行序列讀取的操作一般有執行時載入應用程式的原始碼,編譯,或者測試。
第一件你注意到的但無力改變的事情莫過於,NFS對於小檔案的讀取效能簡直無法相信。NFS效能很強悍很可能是因為由於大量預讀和快取操作。我對於NFS效能比本地虛擬檔案系統好沒有很好地理論解釋。
這裡的VMware共享資料夾正好可以幹掉VirtualBox共享資料夾。VirtualBox共享資料夾的讀取效能簡直糟透了。如果你看過原始資料,你會發現吞吐率從沒超過100MB/s,然後VMware從沒低於500MB/s,甚至高峰時是900MB/s。
有意思的是,有時候虛擬中的本地檔案系統效能竟然比宿主機的好。這個測試用的是原始不帶使用者空間快取的read()系統呼叫。很可能虛擬機器管理器會為虛擬機器的讀操作進行提前快取,所以它們的效能會比需要進行上下文交換的宿主機作業系統核心要好。以上理論也可以從呼叫fread()的基準測試程式的原始資料中得出。在那些測試中,宿主機的本地檔案系統每次都能打扮虛擬機器的檔案系統(譯註:fread()和read()的很大不同之一是,前者帶緩衝,後者不帶緩衝,因此這裡如果都有緩衝,顯然本地檔案系統效能要好)。
大檔案的隨機讀取
這裡測試隨機從64MB檔案讀取任意大小的塊的吞吐量,和上面一樣是讀取各種記錄大小。這個檔案是之前測試檔案的1000倍。這種型別的操作可以在處理資料庫的讀請求時見到。
對比上一個針對小檔案序列讀取的試驗,VMware共享資料夾和VirtualBox共享資料夾的效能差別變得非常大。VirtualBox表現得十分差,以至於你都不容易在上圖中看到它。再一次地,VirtualBox的吞吐量從沒超過100MB/s,另一方面,VMware的峰值卻是7GB/s。因為VirtualBox的吞吐量在各種測試中基本沒差別,我推斷在VirtualBox共享資料夾系統裡有一個程式碼熱路徑限制了其效能,很明顯VirtualBox有地方做的不對。
NFS變得沒有之前的試驗突出了,很可能因為它的預讀取在該測試裡受益有限。儘管如此,相比其他選擇,NFS仍然表現得非常好。
但是,就像之前的實驗一樣,我們仍然能發現在虛擬機器裡的效能比宿主機的要好,這還是因為虛擬機器管理器會很聰明的做快取操作,然而宿主機的原始的系統呼叫是不會允許這種事情發生的。
小檔案序列寫
讓我們看看針對小檔案的序列寫操作。這種情況很精確的描述了儲存段狀態、臨時檔案,或者編寫新的原始碼檔案。
第一個值得注意的事情是,針對這種寫操作NFS效能變得十分差。這裡可沒有供NFS做的快取操作,所以你必須支付因為網路開銷帶來的代價,以及在宿主機那裡再寫到磁碟,最後還要等待VM(虛擬機器)寫操作成功訊號。天哪!
各種”本地“檔案系統表現得都非常好,又一次虛擬機器打敗了宿主機,再一次,這還是因為虛擬機器管理器的快取操作。
共享檔案系統表現相近,但是本次試驗的VirtualBox明顯地擊敗了VMware。
大檔案隨機寫
我們要看的最後一張表是測試隨機寫一個大檔案(64MB)。就像我們的大檔案隨機讀測試一樣,這是一個針對資料庫如何表現的很好地測試。
這裡真的和小檔案序列寫的實驗差不多,因為這裡測試的是大檔案,所以不同測試之間的區別會大一些,但是除此之外,結果基本上一樣。
NFS在寫的時候表現依然糟糕。VirtualBox共享資料夾在寫操作上繼續打敗VMware,並且虛擬機器管理器效能還是比宿主機好。
虛擬機器管理器表現得比宿主機好是我最感興趣的地方。測試結果明顯的標示,虛擬機器管理器一定是謊稱同步寫(譯註:而非真實同步寫)。這也就證實了我用Packer看到的,如果虛擬機器沒有被正確的關閉,你提交的那些寫操作就會丟失。虛擬機器的fsync()呼叫不是表示資料被寫到了宿主機硬碟上,只是將寫操作提交給了虛擬機器管理器。
整體分析
置於共享檔案系統,VMware有你想要的虛擬機器管理器。載入web頁面,執行測試用例,編譯軟體等都屬於繁重讀操作。VMware共享資料夾的讀效能會幹掉VirtualBox,儘管VirtualBox共享資料夾的寫效能稍微比VMware好一點。
如果你可以選擇使用NFS,那麼就用NFS。再次強調,讀效能要比寫效能有價值的多。
虛擬機器管理器讀/寫效能都很出色(因為它作弊)。由於以上資料,我肯定會專注於Vagrant新的只用本地檔案系統的同步資料夾實現(例如rsync,或者用本地檔案系統作為NFS客戶端而不是服務端)。
更直接地:如果你用虛擬機器進行開發,如果可能的話,把資料庫檔案移出共享檔案系統。你會看到很大的效能提升。
最後,我不認為以上結果有令人非常驚訝的地方,自從2010年後,Vagrant已經支援NFS同步資料夾,因為我們很早就意識到共享資料夾的效能很差。但是,用一些資料去標示不同的行為是值得做的,並且,這也為每一個系統在做什麼提供了一些有意思的見解。
測試軟體,配置,原始資料
宿主機是一個2012年的Retina MacBook Pro,硬碟256G SSD,執行Mac OS X10.9.1作業系統,這裡標示成本地。
VirtualBox版本是4.3.4,執行Ubuntu12.04虛擬機器,其中安裝並使用了VirtualBox客戶外掛。測試中的VirtualBox的跟裝置被格式化城ext3檔案系統。在跟裝置上的測試被標示成VirtualBox本地。然而在共享檔案系統(vboxsf)上的測試被標示成VirtualBox共享資料夾(vboxsf)。
VMware Fusion版本是6.0.2執行Ubuntu12.04,其中安裝並使用了VMware Tools 5.0。測試中VMware中的跟裝置被格式化城ext3檔案系統。在跟裝置上的測試被標示成VMware本地。然而在共享檔案系統(vmhgfs)上的測試被標示成VMware共享資料夾(vmhgfs)。
NFS伺服器是OS X 10.0.1附帶並構建的。NFS客戶端來自於Ubuntu12.04中的nfs-common安裝包,在UDP之上採用NFS協議3,在NFS上的測試被標示成NFS in VirtualBox。
基準測試軟體是 Iozone Filesystem Benchmark從用於64位linux的原始碼中編譯而來。同樣的二進位制被用於每一個測試場景,除了本地測試是用的一個從原始碼編譯而來的lozone 32位OS X二進位制。Lozone的引數是-Racb。
除了以上提及的,剩餘的設定和沒提到的都是預設或者沒有用到。
以上測試的原始資料可以在這個 Excel workbook中獲取。還有很多其他圖示在這個imgur album中。
附註:
[1]:這是一個標準的web開發環境,不是典型的CPU密集型或者RAM敏感型。
- Vagrant wikipedia:http://en.wikipedia.org/wiki/Vagrant_(software)