VPS 基準測試怎麼做才準?yabs.sh、fio、sysbench、iperf3
先執行 yabs.sh 取得概略結果,再手動測試 fio、sysbench 與 iperf3。了解 CPU、記憶體、磁碟與網路數值,以及為何單次測試幾乎沒有參考價值。
VPS 基準測試的意義
VPS 基準測試會測量 4 項指標:單一 CPU 核心的執行速度、機器的記憶體頻寬、儲存裝置每秒可處理的小型隨機磁碟作業數量,以及網路連線提供的輸送量。執行一次 yabs.sh 約需 10 分鐘,即可取得這 4 項結果。解讀結果較為困難,因為 VPS(虛擬私有伺服器)會與其他租戶共用實體硬體。因此,同一台機器可能在 03:00 回報一個數值,在 20:00 卻回報截然不同的數值。
本指南會先執行 yabs.sh 取得概略結果,再手動執行其底層工具。自行執行工具,才能變更單一旗標、觀察數值變化,並了解該數值實際測量的內容。請在機器完成設定後執行,不要在此之前執行。新 VPS 的前 10 分鐘中的步驟應先完成,因為仍在套用第一輪更新的機器,會因為與硬體無關的原因而產生不準確的基準測試結果。
進行測量前,先檢查機器
每個不佳基準測試中,有一半問題來自作者不了解測試機器。
nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virtHypervisor vendor: KVM 表示完整虛擬化,因此您會執行自己的核心。systemd-detect-virt 顯示 lxc 或 openvz 則表示容器虛擬化:您會共用主機核心,而 CPU 和記憶體限制是 cgroup(控制群組)設定,不是虛擬硬體。在 cgroup v2 系統上,您可以直接讀取 CPU 限制。
cat /sys/fs/cgroup/cpu.maxmax 100000 表示沒有配額。200000 100000 表示每個 100000 微秒的週期中,您可以使用 200000 微秒的 CPU 時間,相當於 2 個核心的配額。標示為 4 vCPU、但配額只有 2 個核心的方案,得分永遠不會等同於 4 個核心,而且沒有任何基準測試工具會列出原因。
df -hT / 之所以重要,原因不同:它代表 Type 欄。如果顯示 overlay,表示您位於容器內,下面的磁碟測試需要變更。現在請記下這點。
全程監控 steal time
steal time 是虛擬 CPU 已準備執行,但虛擬機器管理程式將實體核心交給其他工作所占的時間比例。這是判斷結果是否受到鄰近租戶影響,而非硬體本身影響的最有用單一指標。
vmstat 1 10查看右側的 st 欄位。穩定維持在 0 或 1 屬於正常。持續高於 5 表示該時刻的主機超額配置,因此您在這段期間記錄的所有 CPU 數值都會偏低,原因不在您的機器。top 會在 CPU 列中顯示與 %st 相同的數值。執行基準測試時,在第二個 SSH 工作階段中持續執行 vmstat 1,並將 steal 數值記錄在每項結果旁。
從 yabs.sh 開始
yabs.sh(Yet Another Bench Script)是一個 shell 指令碼,會下載靜態編譯的 fio、iperf3 和 Geekbench 二進位檔,執行這些工具,並輸出一份摘要。它是 VPS 效能基準測試討論中常用的共同格式,因此 yabs 輸出是與他人快速比較結果的方式。
該專案提供的單行形式如下。
curl -sL yabs.sh | bash這會將該 URL 目前提供的內容直接傳送給 shell。請先下載並閱讀內容,再執行。
curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.sh使用管線執行時,請將旗標放在 -s -- 之後;執行本機副本時,則直接放在檔名之後。常用旗標如下:-f 略過磁碟測試,-i 略過網路測試,-g 略過 Geekbench,-r 將 iperf3 測試位置減少為 2 個,-j 以 JSON 格式輸出結果,-w results.json 將該 JSON 寫入檔案。
bash yabs.sh -r -w yabs-run1.json首次執行前,請注意以下 2 點。Geekbench 會上傳測試結果,並輸出 public.browser.geekbench.com URL。任何取得該連結的人都能查看您的 CPU 型號和分數。-g 會完全略過此測試。其次,iperf3 階段會將實際網路流量傳送至數個地區的伺服器,這會計入您每月的頻寬額度。在 1 Gbit/s 連線上,完整的網路測試階段可能傳輸數十 GB,因此額度較少時請使用 -r,計量型連線則請使用 -i。
yabs 輸出中各部分的含義
磁碟區段會使用 fio,以 50/50 的讀取與寫入比例,測試 4k、64k、512k 和 1m 這 4 種區塊大小。每種大小都會回報 IOPS(每秒輸入/輸出作業數)和頻寬。對資料庫、郵件伺服器,或任何會執行大量小型寫入的工作負載而言,應重點查看 4k 列,因為大多數伺服器 IO 都是小型且分散的作業。1m 列則適合評估備份和影片工作負載,因為這些工作會連續搬移大量位元組。
網路區段會使用平行串流,與數個區域的公用伺服器執行 iperf3 測試,並測量兩個方向。低數值應視為需要調查的問題,而不是確定的結論,因為公用 iperf3 伺服器由多人共用,且經常已達飽和。因此,結果不佳可能是遠端端點造成的。
Geekbench 區段會提供單核心分數和多核心分數。單核心分數可預測單一要求、單次編譯或單一查詢完成的速度。多核心分數主要表示你實際取得了多少個核心。
磁碟:自行執行 fio
fio(flexible IO tester)是 yabs 磁碟區段所使用的工具。直接執行 fio 才能真正理解各個旗標的作用。
sudo apt update && sudo apt install -y fio sysbench iperf3在您實際關心的檔案系統上,執行佇列深度為 32 的 4k 隨機讀取測試:
fio --name=randread4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randread --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reporting輸出中的摘要列如下所示。
read: IOPS=184k, BW=719MiB/s (754MB/s)(42.1GiB/60001msec)在摘要下方,fio 會輸出 clat percentiles 區塊。值得引用的是第 99.00 百分位數,因為它表示每 100 個要求中,最慢的 1 個要求等待了多久。平均延遲會掩蓋使用者實際感受到的停頓。
--direct=1使用O_DIRECT開啟檔案,因此讀取會繞過核心頁面快取。如果沒有這個旗標,在具有 8G RAM 的機器上,第二次讀取 2G 檔案時會直接由記憶體提供資料,fio 會回報數百萬 IOPS。這個數字本身沒有錯,但它反映的是記憶體效能。--ioengine=libaio提交非同步要求,因此--iodepth=32能讓 32 個要求同時處於處理中。使用psync等同步引擎時,超過 1 的 iodepth 完全不會產生作用,因此測量的是一次一個要求。--time_based --runtime=60會固定執行 60 秒,而不是固定處理某個工作量。因此,快速磁碟和慢速磁碟會使用相同的實際時間,比較結果較為公平。--size=2G設定測試檔案大小。請讓檔案大於資料路徑上的任何快取,並先確認有足夠的可用空間。
隨機寫入只需將命令中的 --rw=randwrite 改為另一個值。請分開執行測試,然後刪除檔案。
fio --name=randwrite4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randwrite --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reporting
rm -f ./fio-testfile若要使用更接近實際網路流量的混合模式,請使用 --rw=randrw --rwmixread=70。您使用的儲存裝置類型對結果的影響,大於任何旗標;相關差異請參閱 VPS 上 NVMe 與 SATA SSD 儲存裝置的差異。
fio 因 Unknown error -1 停止時
並非所有檔案系統都提供直接 I/O。overlay 是 Docker 預設提供給容器的檔案系統,數個網路檔案系統也不支援 O_DIRECT,因此 libaio 會提交核心無法完成的要求,fio 便會放棄:
fio: io_u error on file ./fio-testfile: Unknown error -1: read offset=0, buflen=4096
fio: pid=1234, err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1先執行 df -hT .。如果 Type 欄顯示 overlay,請將 --filename 指向實體儲存體上的路徑,例如 bind mounted volume;或者改在主機上執行 fio,而不要在容器中執行。如果無法使用實體儲存體,至少可以先執行 buffered synchronous 測試,以確認指令本身正確。
fio --name=randread4k-buffered --filename=./fio-testfile --size=256M --bs=4k \
--rw=randread --ioengine=psync --direct=0 --numjobs=1 \
--runtime=15 --time_based --group_reporting
rm -f ./fio-testfile請正確解讀這次執行結果。第一次測試後,256M 檔案會留在 page cache 中,因此 IOPS 數值反映的是 RAM 的效能。可用它確認 fio 已安裝且能正確解析 flags。不要將此數值當作磁碟效能結果引用。
為什麼 dd 不是磁碟基準測試
dd 常出現在許多 VPS 討論串中,但它只能回答一個特定問題。
dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtest這會測量單一執行緒、同時只有一個請求處理中的循序寫入吞吐量。這是合理的基本檢查,但無法反映隨機 IO,也無法反映同時到達 32 個請求時的情況。省略 oflag=direct 後,測量結果大多反映核心將寫入資料接受到記憶體中的速度。因此,論壇文章中引用的 dd 數值通常都不切實際。
CPU:sysbench cpu
sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) run應保留的數值是 events per second。先執行單執行緒測試。這個數值會決定單一 PHP 請求完成或單一編譯工作完成的速度,而且在價格相同的主機之間差異通常最大。接著使用所有執行緒執行測試,以確認 vCPU 是獨立核心,還是共用單一核心的時間片段。
請明確了解此測試的測量內容:sysbench cpu 會使用 64 位元整數運算反覆尋找質數。它不會以接近實際工作負載的方式測試記憶體頻寬、向量單元或快取,因此適合用來比較兩台主機,不適合預測應用程式的實際執行效能。
Ubuntu 24.04 隨附 sysbench 1.0.20,測試名稱必須放在前面。從舊文章複製含有 --test=cpu 的命令,會得到 WARNING: the --test option is deprecated。sysbench 0.4 與 sysbench 1.0 的分數完全不可比較,因此不要拿未標明版本的公開數值與自己的結果比較。
記憶體:sysbench memory
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=write --threads=1 run
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=read --threads=1 run結果單位為 MiB/sec,而且在每台機器上,讀取速度都比寫入速度快。請將 --memory-block-size 設為 1M,並在所有比較中的主機上保持一致。在 1K 下,數值會大幅下降,因為每次操作的額外負擔會增加 1000 倍,最後測量到的是迴圈成本,而不是記憶體頻寬。這是已發布的記憶體分數中最常不一致的旗標。
網路:iperf3
測試吞吐量的正確方式,是對你所控制的另一台機器進行測試。這樣你才能知道兩端正在執行的工作。
在遠端:
iperf3 -s這會在 TCP 5201 上監聽。僅允許測試來源的位址連線至此連接埠,完成後立即關閉。VPS 上的基本 ufw 防火牆規則說明相關語法。
從受測試的 VPS 執行:
iperf3 -c 203.0.113.10 -t 30
iperf3 -c 203.0.113.10 -t 30 -R
iperf3 -c 203.0.113.10 -t 30 -P 8第一個指令會測量受測機器的上傳速度。-R 會反轉傳輸方向,因此測量下載速度。-P 8 會開啟 8 個平行資料流。
請同時執行單一資料流版本和平行版本,因為兩者回答的問題不同。單一 TCP 連線能承載的未確認資料量,最多取決於其視窗大小。因此,其上限大致等於視窗大小除以往返時間。延遲為 80 ms、視窗大小為 4 MB 時,即使底層連線速度更快,上限也約為 400 Mbit/s。單一資料流的數值表示一次下載可取得的速度。平行資料流的數值表示連線的容量。
執行測試時,請留意頻寬用量上限。以 1 Gbit/s 傳輸 30 秒約會傳送 3.75 GB,而且你會在每個方向執行數次。
參考數據,以及如何解讀您的結果
The data behind this chart
[
{
"device": "Local NVMe",
"iops_4k_read": "180,000"
},
{
"device": "Local SATA SSD",
"iops_4k_read": "90,000"
},
{
"device": "Network block",
"iops_4k_read": "12,000"
},
{
"device": "Spinning disk",
"iops_4k_read": "180"
}
]已發布的結果中,本機 NVMe 磁碟區通常接近 180,000 個 4k 隨機讀取 IOPS。本機 SATA SSD 約為 90,000。網路連接的區塊儲存中,每個要求都必須先經過網路才能抵達磁碟,因此通常接近 12,000;旋轉式磁碟約為 180,因為每個隨機要求都需要移動實體磁頭。
這些是各類儲存裝置通常公布的數據,不是單一主機的測量結果。請僅將其用於確認您自己的結果是否處於合理數量級。如果標示為 NVMe 的方案測得的 4k IOPS 只有幾千,請先確認 --direct=1 是否已啟用。若已啟用,則可能是儲存裝置不符合產品頁面的描述,或是您與非常忙碌的鄰近租戶共用該儲存裝置。
為什麼單次執行不能作為基準測試
單一結果只是共用機器在某一分鐘的快照。請將它視為一個樣本。
- 每項測試至少執行五次,分散在不同時段,且至少涵蓋兩天。保留中位數和分布範圍。發布沒有分布範圍的結果,就是行銷數據。
- 在每次執行旁記錄 steal time。捨棄
st偏高的執行結果,或至少註明這一點。 - 以兩種持續時間執行磁碟測試。許多方案提供會隨時間恢復的突發 IOPS 額度,因此 60 秒的 fio 執行結果測量的是突發效能,而
--runtime=600測量的是下限。下限才是狀況不佳時可取得的效能。 - 確認沒有其他程式正在執行。
unattended-upgrades在 CPU 測試期間開始 apt 交易會實際影響測試分數,而每次執行前進行ps -e -o comm= | grep -E 'apt|dpkg'只需一秒。 - 一次只變更一個變數。不同的工具版本、區塊大小或執行緒數量會產生無法比較的數據,無論它們看起來多麼相似。
比較兩家供應商時,請在同一天的相同時段執行測試。否則測量到的就是時段差異。
最後再對自己的工作負載進行基準測試
合成測試工具可以對機器排名。只有自己的工作負載能告訴你機器是否足夠。請測量你實際執行的工作所需時間。
time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgz這會壓縮幾百 MB 的資料,因此會同時測試 CPU 和磁碟;任一者變動,結果都會跟著變化。出現 Removing leading / from member names 警告是正常的。更好的做法是測量自己的建置、最慢的查詢,或頁面呈現時間。某個主機的建置需要 4 分鐘,另一個主機需要 7 分鐘;無論 Geekbench 的結果為何,這已經回答了問題。這項測量也能告訴你,升級機器何時不再值得付費。這點很重要,因為你可能會先閱讀VPS 每月實際費用,或將工作負載移至專用伺服器。
FAQ
為什麼我每次執行基準測試,結果都不同?
VPS 會與其他租戶共用實體 CPU、儲存設備和網路,因此結果取決於當時其他租戶正在執行的工作。在測試期間執行 vmstat 1,並查看 st 欄:持續高於 5 的 steal time 表示主機當時負載很高,而你的 CPU 分數偏低並非由你的機器本身造成。解決方法是改善測試方式,而不是調整設定。每項測試在不同時段執行至少 5 次,然後回報中位數及結果分布。
為什麼 fio 回報數百萬 IOPS?
幾乎都是因為缺少 --direct=1。沒有這項設定時,fio 會透過核心頁面快取讀取資料。因此,第一次讀取後,2G 測試檔案會由 RAM 提供,你實際測量的是記憶體頻寬。加入 --direct=1,並確保測試檔案大於路徑上的所有快取。如果 --direct=1 隨後因 err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1 而失敗,請執行 df -hT .:Type 的 overlay 不支援 O_DIRECT,因此請將測試指向實際儲存設備。
yabs.sh 本身是否足夠?
若只是初步查看,足夠。它會以 4 種區塊大小執行 fio、以雙向執行 iperf3,並輸出一份其他人也能閱讀的摘要。當你想了解某個數值為何如此時,它就不夠了,因為你無法針對每項測試調整其 flags。yabs 結果看起來不合理時,請直接使用 fio 或 sysbench 重現測試,並一次只變更 1 個 flag。
哪個單一數值最能預測應用程式的實際使用感受?
對大多數網頁和資料庫工作負載而言,依重要性排序是單核心 CPU 速度,以及 4k 隨機讀取延遲。頻寬數據看起來很突出,卻很少真正決定效能,因為一般要求的資料量很小。請引用 fio clat percentiles 區塊中的第 99 百分位數,而非平均值,因為每 100 次要求中最慢的那 1 次,才是使用者會察覺的延遲。
執行基準測試前需要安裝任何程式嗎?
fio、sysbench 和 iperf3 都已包含在 Ubuntu 和 Debian 的套件庫中:sudo apt install -y fio sysbench iperf3。yabs.sh 只需要 curl,因為它會為缺少的項目下載靜態二進位檔。完成後請刪除所有測試檔案,因為留在 20G 磁碟上的 2G fio 檔案,幾週後可能會成為某人收到磁碟已滿警示的原因。