Comparing Filesystem Performance in Virtual Machines

Mitchell Hashimoto

比較虛擬機器中的檔案系統效能

原文由 Mitchell Hashimoto 發布,訂閱此部落格

多年來,使用 Vagrant 的虛擬機器開發環境,其主要瓶頸一直是檔案系統效能。CPU 的差異很小,幾乎察覺不到,而記憶體只有在同時運行多個虛擬機器時才會成為問題。

我花了昨天大半天的時間,對常見的檔案系統機制進行基準測試與分析,現在在此與大家分享結果。

我會先從結果分析開始,因為這對大多數人來說是最有意思的部分。確切的測試方法、使用的軟體,以及原始數據,都可以在這段分析之後找到。

在下方展示的每一張圖表中,我們都是以某種方式測試檔案的讀取或寫入。每張圖表中寫入檔案的總大小都是固定的。Y 軸是吞吐量,單位為 KB/s。X 軸則是「record size」,也就是每次讀寫的資料區塊大小,單位為 KB。

不同的測試環境包括 native、VirtualBox native、VMware native、VirtualBox 共享資料夾(vboxsf)、VMware 共享資料夾(vmhgfs)以及 NFS。所謂的「native」環境,指的是在該環境中使用其本身的檔案系統。「native」是在主機上,「VirtualBox native」則是在 VirtualBox 虛擬機器內的根裝置上,以此類推。NFS 僅在 VirtualBox 上進行測試,因為其效能特性在 VirtualBox 和 VMware 上應該是相似的。

在每一張圖表中,吞吐量(Y 軸)越高越好。

小檔案循序讀取

首先是對一個 64 KB 檔案的循序讀取測試,測試了不同的讀取 record size。小檔案循序讀取在現實中的應用情境,例如載入應用程式的原始碼以執行、編譯或測試。

首先讓人無法忽視的是,NFS 在小 record size 下的讀取效能非常驚人。NFS 很可能是透過大量的預讀(read-ahead)操作和快取來達到這種效能。至於 NFS 為何能超越原生的虛擬檔案系統,我並沒有什麼好的理論可以解釋。

在這裡,VMware 共享資料夾的表現完全碾壓 VirtualBox 共享資料夾。VirtualBox 共享資料夾的讀取效能簡直慘不忍睹。如果查看原始數據,你會發現其吞吐量從未超過 100 MB/s,而 VMware 則從未低於 500 MB/s,峰值甚至超過 900 MB/s。

有趣的是,虛擬機器內的原生檔案系統有時反而比主機上的原生檔案系統表現更好。這項測試使用的是原始的 read 系統呼叫,完全沒有使用者空間的緩衝。很有可能 hypervisor 會為其虛擬機器的讀取操作進行緩衝,因此減少了切換到原生核心的次數,從而獲得更好的效能。查看 fread 基準測試的原始結果數據,也進一步支持了這個推論。在那些測試中,原生檔案系統每次都勝過虛擬檔案系統。

大檔案隨機讀取

這項測試是針對一個 64 MB 檔案,隨機讀取其中不同區塊的吞吐量,同樣測試了不同的讀取 record size。這個檔案比前一項測試大了 1000 倍。這類行為常見於會觸及檔案系統的資料庫讀取。

與小檔案循序讀取相比,VMware 共享資料夾與 VirtualBox 共享資料夾之間的差距被大幅拉開。VirtualBox 的表現差到在圖表上幾乎看不見。同樣地,VirtualBox 的吞吐量峰值從未超過 100 MB/s。另一方面,VMware 的峰值則高達 7 GB/s。由於 VirtualBox 在各種測試案例中的吞吐量變異非常小,我推測其共享資料夾系統中有一段關鍵的熱點程式碼限制了效能。他們顯然在某些地方做錯了。

NFS 的優勢在這個測試中就沒那麼明顯,很可能是因為預讀帶來的好處在此情境下無法體現。即便如此,NFS 相較於其他選項,表現依然非常出色。

而且,就像小檔案循序讀取一樣,我們仍然看到虛擬機器內的效能優於外部。同樣地,這可以歸因於 hypervisor 做了巧妙的緩衝,而對主機的原始系統呼叫則無法做到這一點。

小檔案循序寫入

接下來看看小檔案循序寫入的效能。這最能描述儲存 session 狀態、暫存檔或寫入新原始碼檔案的情境。

首先最明顯的是,NFS 在這類寫入上的效能非常糟糕。在這種情況下,NFS 幾乎無法做任何有效的快取,因此你必須完全承擔網路開銷的代價,接著在主機端寫入磁碟,最後還要等待虛擬機器收到寫入成功的確認(ack)。真是慘痛。

各種「native」檔案系統的表現都非常好。同樣地,虛擬機器的效能超越了主機。這同樣可以歸因於 hypervisor 中的緩衝機制。

共享檔案系統的表現很接近,但在這個測試案例中,VirtualBox 明顯勝過 VMware。

大檔案隨機寫入

我們要看的最後一張圖表,是對一個大型(64 MB)檔案進行隨機寫入的測試結果。就像我們的大檔案隨機讀取測試一樣,這是衡量資料庫效能的一個很好的測試。

這裡與小檔案循序寫入相比,其實沒有太大差異。由於是大型檔案,不同測試環境之間的差距變得更大,但除此之外,結果大致相同。

NFS 在寫入方面依然表現糟糕。VirtualBox 共享資料夾在寫入上仍持續勝過 VMware,而 hypervisor 的效能也依然超越主機。

Hypervisor 效能超越主機是對我來說最有趣的一點。這項測試的結果清楚顯示,hypervisor 為了效能,一定在同步寫入(synced writes)上撒了謊。這也印證了我在 Packer 上看到的情況,也就是如果虛擬機器沒有正常關機,已提交的寫入就會遺失。在虛擬機器中執行 fsync() 並不代表資料已經寫入主機,而只是表示資料已在 hypervisor 內提交。

整體分析

就共享檔案系統而言,VMware 擁有你想要的特性。載入網頁、執行測試套件和編譯軟體等操作,都是以讀取為主。VMware 共享資料夾的讀取效能徹底擊敗 VirtualBox,而 VirtualBox 共享資料夾的寫入效能也僅僅比 VMware 好一點點而已。

如果你有使用 NFS 的選項,就用它吧。再次強調,讀取效能遠比寫入效能來得重要。

Hypervisor 的讀寫效能非常出色(因為它們作弊了)。有了這些數據,我肯定會更專注於 Vagrant 中僅使用原生檔案系統的新同步資料夾實作(例如 rsync,或是將主機作為 NFS 客戶端而非伺服器端)。

不過,更立即有用的建議是:如果你使用虛擬機器進行開發,請盡可能將資料庫檔案移出共享檔案系統。你很可能會看到巨大的效能提升。

最後,我認為這些結果並沒有什麼太大的驚喜。Vagrant 從 2010 年起就支援 NFS 同步資料夾,因為我們很早就意識到共享資料夾的效能很差。但能有這些實際數據來展示不同系統的行為差異,還是很有價值的,也讓我們得以一窺每個系統背後可能的運作方式。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言