SSD Nodes Learn 8GB RAM — $66/năm
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-01

Benchmark VPS đúng cách với yabs.sh, fio, sysbench

Đo VPS bằng yabs.sh trước, rồi chạy fio, sysbench và iperf3 thủ công. Hiểu từng chỉ số, tác động của tenant dùng chung và vì sao một lần chạy gần như vô nghĩa.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Benchmark VPS nghĩa là gì

Benchmark VPS là đo 4 yếu tố: tốc độ chạy của một core CPU, băng thông bộ nhớ của máy, số thao tác đĩa ngẫu nhiên nhỏ mà storage có thể xử lý mỗi giây, và throughput mà đường truyền mạng cung cấp. Một lần chạy yabs.sh cho bạn cả 4 kết quả trong khoảng 10 phút. Phần khó hơn là đọc kết quả, vì VPS (virtual private server) dùng chung phần cứng vật lý với các tenant khác. Do đó, cùng một máy có thể báo một con số lúc 03:00 và một con số rất khác lúc 20:00.

Kế hoạch là chạy yabs.sh để có đánh giá nhanh, sau đó tự chạy từng tool bên dưới. Tự chạy các tool này cho phép bạn thay đổi một flag, theo dõi con số thay đổi và hiểu con số đó thực sự đo gì. Hãy thực hiện sau khi thiết lập xong máy, không phải trước đó. Các bước trong 10 phút đầu tiên trên một VPS mới cần được thực hiện trước, vì một máy vẫn đang áp dụng đợt cập nhật đầu tiên sẽ cho kết quả benchmark không chính xác vì những lý do không liên quan đến phần cứng.

Kiểm tra máy trước khi đo

Một nửa số benchmark kém là do tác giả không hiểu rõ máy đang đo.

nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virt

Hypervisor vendor: KVM nghĩa là ảo hóa toàn phần, nên bạn chạy kernel của riêng mình. Việc in lxc hoặc openvz trong systemd-detect-virt nghĩa là ảo hóa container: bạn dùng chung kernel của host, còn giới hạn CPU và bộ nhớ là các thiết lập cgroup (control group), không phải phần cứng ảo. Trên hệ thống cgroup v2, bạn có thể đọc trực tiếp giới hạn CPU.

cat /sys/fs/cgroup/cpu.max

max 100000 nghĩa là không có quota. 200000 100000 nghĩa là bạn có thể dùng 200000 microseconds CPU trong mỗi khoảng thời gian 100000 microseconds, tương đương quota của hai core. Một gói được quảng cáo là 4 vCPU nhưng có quota bằng hai core sẽ không bao giờ đạt điểm như bốn core, và không có công cụ benchmark nào in ra một dòng cho biết lý do.

df -hT / quan trọng vì một lý do khác: cột Type. Nếu cột này hiển thị overlay, bạn đang ở trong container và bài kiểm tra disk bên dưới cần được thay đổi. Hãy ghi lại ngay.

Theo dõi steal time trong toàn bộ thời gian

Steal time là phần thời gian CPU ảo của bạn đã sẵn sàng chạy nhưng hypervisor lại cấp core vật lý cho máy khác. Đây là tín hiệu đơn lẻ hữu ích nhất để xác định kết quả bị ảnh hưởng bởi các máy lân cận thay vì do phần cứng.

vmstat 1 10

Đọc cột st ở bên phải. Giá trị ổn định là 0 hoặc 1. Giá trị duy trì trên 5 nghĩa là host đang bị phân bổ quá mức tại thời điểm đó. Vì vậy, mọi số liệu CPU bạn ghi nhận trong khoảng thời gian này đều thấp, không phải do máy của bạn. top hiển thị cùng số liệu với %st trên dòng CPU. Giữ vmstat 1 chạy trong một phiên SSH thứ hai khi bạn benchmark, rồi ghi lại giá trị steal bên cạnh từng kết quả.

Bắt đầu với yabs.sh

yabs.sh (Yet Another Bench Script) là một shell script tải các binary tĩnh của fio, iperf3 và Geekbench, chạy chúng rồi in một bản tóm tắt. Đây là cách trao đổi phổ biến trong các cuộc thảo luận về benchmark VPS, vì vậy output của yabs là cách nhanh nhất để so sánh kết quả với người khác.

Dạng một dòng do chính dự án cung cấp là:

curl -sL yabs.sh | bash

Lệnh này pipe mọi nội dung URL hiện cung cấp trực tiếp vào shell. Hãy tải xuống, đọc nội dung, rồi mới chạy.

curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.sh

Khi pipe, đặt các flag sau -s --. Khi chạy bản sao cục bộ, đặt chúng ngay sau tên file. Các flag hữu ích gồm: -f bỏ qua disk test, -i bỏ qua network test, -g bỏ qua Geekbench, -r giảm số location của iperf3 xuống còn 2, -j in kết quả dưới dạng JSON và -w results.json ghi JSON đó vào một file.

bash yabs.sh -r -w yabs-run1.json

Có 2 điều cần biết trước lần chạy đầu tiên. Geekbench upload kết quả của bạn và in một URL công khai trên browser.geekbench.com. Bất kỳ ai có link đó đều có thể xem model CPU và điểm số của bạn. -g bỏ qua hoàn toàn test này. Thứ hai, bước iperf3 truyền network traffic thực qua các server ở nhiều region, và lượng traffic này được tính vào bandwidth allowance hằng tháng của bạn. Trên đường truyền 1 Gbit/s, một network stage đầy đủ có thể truyền hàng chục gigabyte, vì vậy hãy dùng -r nếu allowance thấp và -i trên đường truyền tính phí theo lưu lượng.

Ý nghĩa của từng phần trong kết quả yabs

Phần disk chạy fio với tỷ lệ đọc/ghi 50/50 ở 4 kích thước block: 4k, 64k, 512k và 1m. Phần này báo IOPS (số thao tác input/output mỗi giây) và băng thông cho từng kích thước. Dòng 4k đáng chú ý đối với database, mail server hoặc mọi workload thực hiện nhiều thao tác ghi nhỏ, vì phần lớn IO của server có kích thước nhỏ và phân tán. Dòng 1m phù hợp để đánh giá backup và video, nơi dữ liệu được truyền theo các chuỗi byte dài.

Phần network chạy iperf3 với các public server ở nhiều khu vực, theo cả hai chiều và sử dụng các parallel stream. Hãy xem kết quả thấp ở đây là một vấn đề cần kiểm tra, không phải kết luận cuối cùng, vì các public iperf3 server được dùng chung và thường bị bão hòa. Kết quả kém có thể do phía server ở đầu xa.

Phần Geekbench cung cấp điểm single core và multi core. Điểm single core cho biết một request, một lần compile hoặc một query hoàn tất nhanh đến mức nào. Điểm multi core chủ yếu cho biết bạn thực sự được cấp bao nhiêu core.

Disk: tự chạy fio

fio (flexible IO tester) là công cụ phía sau phần disk của yabs. Chạy trực tiếp fio sẽ giúp bạn hiểu rõ ý nghĩa của các flag.

sudo apt update && sudo apt install -y fio sysbench iperf3

Bài test đọc ngẫu nhiên 4k với queue depth bằng 32, trên filesystem bạn thực sự quan tâm:

fio --name=randread4k --filename=./fio-testfile --size=2G --bs=4k \
  --rw=randread --ioengine=libaio --iodepth=32 --direct=1 \
  --runtime=60 --time_based --group_reporting

Dòng tóm tắt cần đọc trong output có dạng như sau.

read: IOPS=184k, BW=719MiB/s (754MB/s)(42.1GiB/60001msec)

Bên dưới, fio in ra một block clat percentiles. Phân vị 99.00 là giá trị đáng trích dẫn, vì nó cho biết request chậm nhất trong mỗi 100 request đã phải chờ bao lâu. Latency trung bình che khuất chính những lần bị stall mà người dùng nhận thấy.

  • --direct=1 mở file với O_DIRECT, nên các thao tác đọc bỏ qua kernel page cache. Nếu không dùng tùy chọn này, lần chạy thứ hai trên file 2G ở máy có 8G RAM sẽ được phục vụ từ memory và fio báo IOPS lên đến hàng triệu. Con số đó là có thật, nhưng đó là con số của memory.
  • --ioengine=libaio gửi các request bất đồng bộ. Nhờ đó --iodepth=32 có thể duy trì 32 request đang được xử lý. Với engine đồng bộ như psync, iodepth lớn hơn 1 hoàn toàn không có tác dụng, nên bạn đo từng request một.
  • --time_based --runtime=60 chạy trong 60 giây cố định thay vì xử lý một lượng công việc cố định. Nhờ đó disk nhanh và disk chậm có cùng thời gian thực tế, giúp so sánh công bằng hơn.
  • --size=2G đặt kích thước file test. Hãy giữ kích thước này lớn hơn mọi cache trên đường đi và kiểm tra dung lượng trống trước.

Random write dùng cùng command này với --rw=randwrite. Chạy riêng bài test đó, sau đó xóa file.

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

Để mô phỏng hỗn hợp gần với network traffic thực tế hơn, hãy dùng --rw=randrw --rwmixread=70. Loại storage bạn đang sử dụng ảnh hưởng đến kết quả nhiều hơn bất kỳ flag nào. Phần khác biệt giữa NVMe và SATA SSD storage trên VPS giải thích sự khác biệt này.

Khi fio dừng với lỗi Unknown error -1

Direct IO không khả dụng trên mọi filesystem. overlay, filesystem mà Docker cấp mặc định cho container, và một số network filesystem không hỗ trợ O_DIRECT. Vì vậy, libaio gửi một request mà kernel không thể hoàn tất, rồi fio dừng:

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

Trước tiên, chạy df -hT .. Nếu cột Type hiển thị overlay, hãy trỏ --filename đến một đường dẫn trên storage thực, chẳng hạn một volume được bind mount, hoặc chạy fio trên host thay vì trong container. Nếu không thể truy cập storage thực, một lần chạy synchronous có buffering ít nhất cũng xác nhận rằng chính command đó đúng.

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

Cần hiểu đúng ý nghĩa của lần chạy này. Sau lần đầu tiên, file 256M nằm trong page cache, nên chỉ số IOPS phản ánh RAM của bạn. Hãy dùng kết quả này để xác nhận fio đã được cài đặt và các flag được phân tích đúng. Không được coi đây là kết quả của disk.

Vì sao dd không phải là công cụ benchmark ổ đĩa

dd xuất hiện trong nhiều thread về VPS và chỉ trả lời một câu hỏi hẹp.

dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtest

Lệnh này đo thông lượng ghi tuần tự với một thread và một request đang được xử lý. Đây là một phép kiểm tra nhanh hợp lý. Nó không cho biết gì về I/O ngẫu nhiên, cũng không cho biết điều gì xảy ra khi có 32 request đến cùng lúc. Bỏ oflag=direct thì lệnh chủ yếu đo tốc độ kernel nhận các lần ghi vào bộ nhớ, vì vậy các con số dd được trích dẫn trong bài đăng trên forum thường cao một cách phi lý.

CPU: sysbench CPU

sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) run

Chỉ số cần giữ lại là events per second. Trước tiên, hãy chạy với một luồng. Đây là con số quyết định tốc độ hoàn tất một request PHP hoặc một job biên dịch, và chỉ số này thường khác nhau nhiều nhất giữa các host có cùng mức giá. Sau đó, hãy chạy với tất cả các luồng. Kết quả cho biết các vCPU của bạn là các core riêng biệt hay chỉ là các lát thời gian của cùng một core.

Cần hiểu rõ phép đo này: sysbench CPU liên tục tìm số nguyên tố bằng phép tính số nguyên 64 bit. Phép đo này không tạo tải lên băng thông bộ nhớ, vector unit hoặc cache theo cách giống workload thực tế. Vì vậy, nó phù hợp để xếp hạng hai host nhưng không phù hợp để dự đoán ứng dụng của bạn sẽ chạy như thế nào.

Ubuntu 24.04 đi kèm sysbench 1.0.20, trong đó tên test được đặt trước. Nếu copy một command có --test=cpu từ một bài viết cũ, bạn sẽ nhận được WARNING: the --test option is deprecated. Điểm số từ sysbench 0.4 và sysbench 1.0 hoàn toàn không thể so sánh. Vì vậy, không bao giờ so sánh kết quả của bạn với một con số được công bố nếu con số đó không nêu rõ version.

Bộ nhớ: 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

Kết quả được tính bằng MiB/sec, và tốc độ đọc luôn cao hơn tốc độ ghi trên mọi máy. Giữ --memory-block-size ở mức 1M và dùng cùng giá trị này trên mọi host bạn so sánh. Với 1K, con số giảm mạnh vì chi phí cho mỗi thao tác phát sinh thường xuyên hơn 1.000 lần. Khi đó, bạn đang đo chi phí của vòng lặp thay vì băng thông bộ nhớ. Đây là flag thường bị đặt không đồng nhất nhất trong các điểm số bộ nhớ được công bố.

Network: iperf3

Cách kiểm tra throughput chính xác là kiểm tra với một máy thứ hai do bạn kiểm soát, vì khi đó bạn biết cả hai đầu đang làm gì.

Trên máy ở đầu xa:

iperf3 -s

Lệnh này lắng nghe trên TCP 5201. Chỉ mở port cho địa chỉ mà bạn dùng để kiểm tra, rồi đóng port khi hoàn tất. Các quy tắc firewall ufw cơ bản trên VPS trình bày cú pháp.

Từ VPS đang được kiểm tra:

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

Lệnh đầu tiên đo tốc độ upload từ máy đang được kiểm tra. -R đảo ngược hướng truyền, để đo tốc độ download. -P 8 mở tám stream song song.

Hãy chạy cả phiên bản một stream và phiên bản song song, vì chúng trả lời các câu hỏi khác nhau. Một kết nối TCP chỉ có thể giữ lượng dữ liệu chưa được xác nhận bằng kích thước window cho phép. Vì vậy, giới hạn của nó xấp xỉ kích thước window chia cho round-trip time. Với độ trễ 80 ms và window 4 MB, giới hạn này là khoảng 400 Mbit/s, dù link bên dưới có tốc độ cao đến đâu. Giá trị của một stream cho biết một lượt download sẽ đạt được bao nhiêu. Giá trị khi chạy song song cho biết capacity của link.

Trong khi kiểm tra, hãy theo dõi hạn mức bandwidth của bạn. Chạy 30 giây ở tốc độ 1 Gbit/s sẽ truyền khoảng 3.75 GB, và bạn sẽ chạy lệnh này nhiều lần theo cả hai hướng.

Các số liệu tham chiếu và cách đọc kết quả của bạn

ChartTypical published 4k random read IOPS by storage class
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"
  }
]

Volume NVMe cục bộ trong các kết quả được công bố thường đạt khoảng 180,000 IOPS đọc ngẫu nhiên 4k. SSD SATA cục bộ thường đạt khoảng 90,000. Block storage gắn qua network, trong đó mọi request đều phải đi qua network trước khi đến disk, thường chỉ đạt khoảng 12,000. Disk quay đạt khoảng 180, vì mỗi request ngẫu nhiên đều phải di chuyển đầu đọc vật lý.

Đây là các số liệu điển hình được công bố cho từng loại storage, không phải kết quả đo từ một host cụ thể. Chỉ dùng chúng để kiểm tra xem kết quả của bạn có cùng bậc độ lớn hay không. Nếu một plan được bán là NVMe nhưng benchmark chỉ đạt vài nghìn IOPS 4k, trước tiên hãy xác nhận --direct=1 đã được bật. Nếu đã bật, thì storage không đúng như mô tả trên product page, hoặc bạn đang dùng chung storage với một máy hàng xóm đang rất bận.

Vì sao một lần chạy không phải là phép benchmark

Một kết quả chỉ là ảnh chụp tại một phút trên một máy dùng chung. Hãy xem đó là một mẫu.

  • Chạy mỗi bài test ít nhất 5 lần, vào các giờ khác nhau và ít nhất 2 ngày khác nhau. Giữ lại median và độ phân tán. Kết quả được công bố mà không có độ phân tán chỉ là con số marketing.
  • Ghi lại steal time bên cạnh mỗi lần chạy. Loại bỏ các lần chạy khi st cao, hoặc ít nhất ghi rõ điều đó.
  • Chạy disk test với 2 thời lượng. Nhiều gói dịch vụ cấp burst IOPS có thể được nạp lại theo thời gian, nên một lần chạy fio trong 60 giây sẽ đo mức burst, còn --runtime=600 đo mức sàn. Mức sàn là hiệu năng bạn nhận được vào ngày tệ.
  • Kiểm tra để bảo đảm không có tác vụ nào khác đang chạy. unattended-upgrades bắt đầu một apt transaction giữa lúc CPU test đang chạy sẽ làm mất điểm thực tế, còn ps -e -o comm= | grep -E 'apt|dpkg' trước mỗi lần chạy chỉ mất 1 giây.
  • Mỗi lần chỉ thay đổi 1 biến. Các phiên bản tool, block size hoặc thread count khác nhau tạo ra những con số không thể so sánh, dù trông chúng có vẻ tương tự.

Khi so sánh 2 nhà cung cấp, hãy chạy test vào cùng giờ trong cùng ngày. Nếu không, bạn đã đo thời điểm trong ngày.

Benchmark workload của chính bạn trước

Các công cụ benchmark tổng hợp dùng để xếp hạng máy chủ. Chỉ workload của chính bạn mới cho biết một máy có đủ hay không. Hãy đo thời gian cho tác vụ bạn thực sự chạy.

time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgz

Tác vụ này nén vài trăm megabyte, nên kiểm tra đồng thời CPU và disk. Kết quả sẽ thay đổi khi một trong hai thành phần thay đổi. Cảnh báo Removing leading / from member names là bình thường. Tốt hơn nữa, hãy đo thời gian build của chính bạn, query chậm nhất của chính bạn hoặc thời gian render page của chính bạn. Build mất 4 phút trên một host và 7 phút trên host khác đã đủ trả lời câu hỏi, bất kể Geekbench cho kết quả thế nào. Đây cũng là phép đo cho biết khi nào việc trả thêm tiền để nâng cấp máy không còn đáng nữa. Bạn nên biết điều đó trước khi đọc chi phí thực tế mỗi tháng của một VPS hoặc chuyển workload sang dedicated server.

FAQ

Tại sao mỗi lần chạy benchmark tôi lại nhận được kết quả khác nhau?

Một VPS dùng chung CPU vật lý, storage và network với các tenant khác. Vì vậy, kết quả phụ thuộc vào việc các tenant đó đang làm gì tại thời điểm chạy benchmark. Chạy vmstat 1 trong lúc kiểm tra và đọc cột st: steal time duy trì trên 5 nghĩa là host đang bận, nên điểm CPU của bạn thấp vì những nguyên nhân nằm ngoài máy của bạn. Cách xử lý là chuẩn hóa phương pháp, không phải tuning. Chạy mỗi bài kiểm tra ít nhất 5 lần vào các giờ khác nhau. Sau đó báo cáo median cùng với độ phân tán.

Tại sao fio báo hàng triệu IOPS?

Gần như luôn là do thiếu --direct=1. Nếu không có tùy chọn này, fio sẽ đọc qua kernel page cache. Sau lần chạy đầu tiên, file kiểm tra 2G được phục vụ từ RAM, nên bạn thực chất đang đo memory bandwidth. Thêm --direct=1 và giữ file kiểm tra lớn hơn mọi cache trên đường đi. Nếu --direct=1 sau đó thất bại với err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1, hãy chạy df -hT .: một Type của overlay không hỗ trợ O_DIRECT, nên hãy trỏ bài kiểm tra vào storage thực.

Chỉ dùng yabs.sh có đủ không?

Để kiểm tra sơ bộ thì đủ. Công cụ này chạy fio với 4 block size, chạy iperf3 theo cả 2 hướng và chạy Geekbench. Nó in ra một bản tóm tắt mà người khác có thể đọc. Công cụ này không còn đủ khi bạn muốn biết vì sao một con số lại có giá trị như vậy, vì bạn không thể thay đổi flag theo từng bài kiểm tra. Khi kết quả yabs có vẻ không đúng, hãy chạy lại bằng fio hoặc sysbench trực tiếp và thay đổi từng flag một.

Một con số nào dự đoán chính xác nhất cảm nhận của ứng dụng?

Với hầu hết workload web và database, đó là tốc độ CPU single core và độ trễ đọc ngẫu nhiên 4k, theo thứ tự này. Các chỉ số throughput trông ấn tượng nhưng hiếm khi quyết định kết quả, vì một request điển hình có kích thước nhỏ. Hãy báo cáo percentile 99 từ block clat percentiles của fio thay vì giá trị trung bình. Request chậm trong mỗi 100 request là điều người dùng nhận thấy.

Tôi có cần cài đặt gì trước khi benchmark không?

fio, sysbench và iperf3 đều có trong các repository của Ubuntu và Debian: sudo apt install -y fio sysbench iperf3. yabs.sh chỉ cần curl, vì nó tải các static binary cho mọi thành phần còn thiếu. Xóa mọi file kiểm tra sau khi hoàn tất. Nếu để lại file fio 2G trên disk 20G, vài tuần sau nó có thể khiến hệ thống phát cảnh báo disk full.

#benchmarks#fio#sysbench#yabs#iperf3#vps-performance