วิธีทำ Benchmark บน VPS ให้แม่นยำและอ่านค่าเป็น
เรียนรู้วิธีทดสอบประสิทธิภาพ VPS ด้วย yabs.sh, fio, sysbench และ iperf3 อย่างถูกต้อง พร้อมคำแนะนำการตีความตัวเลขที่ผันผวนตามช่วงเวลา เพื่อให้ได้ผลลัพธ์ที่สะท้อนความจริง
ความหมายของการทำ Benchmark บน VPS
การทำ Benchmark บน VPS คือการวัดค่า 4 ประการ ได้แก่ ความเร็วในการประมวลผลของ CPU หนึ่งคอร์, แบนด์วิดท์ของหน่วยความจำ, จำนวนการอ่านเขียนข้อมูลขนาดเล็กแบบสุ่มต่อวินาที (IOPS) ของพื้นที่จัดเก็บข้อมูล และปริมาณข้อมูลที่เครือข่ายสามารถรับส่งได้ การรัน yabs.sh หนึ่งครั้งจะให้ผลลัพธ์ด้าน CPU, ดิสก์ และเครือข่ายภายในเวลาประมาณ 10 นาที สำหรับการวัดแบนด์วิดท์ของหน่วยความจำให้ใช้การทดสอบแยกต่างหากที่ระบุไว้ด้านล่าง การอ่านผลลัพธ์เป็นส่วนที่ยากกว่า เนื่องจาก VPS (virtual private server) มีการใช้ทรัพยากรฮาร์ดแวร์ร่วมกับผู้เช่ารายอื่น ดังนั้นเครื่องเดียวกันอาจให้ค่าที่แตกต่างกันอย่างมากระหว่างเวลา 03:00 น. และ 20:00 น.
แนวทางในที่นี้คือการรัน yabs.sh เพื่อให้เห็นภาพรวมอย่างรวดเร็ว จากนั้นจึงรันเครื่องมือต่างๆ ด้วยตนเอง การรันด้วยตนเองจะช่วยให้คุณสามารถปรับเปลี่ยน flag ทีละตัว สังเกตการเปลี่ยนแปลงของตัวเลข และเรียนรู้ว่าตัวเลขนั้นวัดค่าอะไรกันแน่ ให้ดำเนินการขั้นตอนนี้หลังจากตั้งค่าเครื่องเสร็จสิ้นแล้วเท่านั้น ไม่ควรทำก่อน ขั้นตอนใน สิบนาทีแรกบน VPS ใหม่ ต้องทำก่อนเสมอ เนื่องจากเครื่องที่กำลังอยู่ในระหว่างการอัปเดตชุดแรกจะให้ผลการทดสอบที่ต่ำกว่าความเป็นจริงด้วยเหตุผลที่ไม่เกี่ยวข้องกับประสิทธิภาพของฮาร์ดแวร์เลย
ตรวจสอบเครื่องก่อนทำการวัดผล
ครึ่งหนึ่งของผลการทดสอบประสิทธิภาพที่แย่เกิดจากเครื่องที่ผู้เขียนไม่ได้ทำความเข้าใจอย่างถ่องแท้
nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virtHypervisor vendor: KVM หมายถึงการทำ virtualisation เต็มรูปแบบ ดังนั้นคุณจึงรัน kernel ของตนเอง การพิมพ์ systemd-detect-virt ด้วย lxc หรือ openvz หมายถึงการทำ container virtualisation แทน ซึ่งคุณจะใช้ kernel ร่วมกับโฮสต์ และขีดจำกัดของ CPU และหน่วยความจำจะเป็นการตั้งค่า cgroup (control group) แทนที่จะเป็นฮาร์ดแวร์เสมือน บนระบบ cgroup v2 คุณสามารถอ่านขีดจำกัด CPU ได้จาก cgroup ของคอนเทนเนอร์ โดยพาธต่อไปนี้จะใช้ได้เมื่อ cgroup นั้นถูก mount ไว้ที่ /sys/fs/cgroup
cat /sys/fs/cgroup/cpu.maxmax 100000 หมายความว่า cgroup นี้ไม่มีโควตาเป็นของตนเอง แต่ cgroup ระดับบนยังคงสามารถกำหนดโควตาได้ 200000 100000 หมายความว่าคุณสามารถใช้ CPU ได้ 200000 ไมโครวินาทีในทุกช่วงเวลา 100000 ไมโครวินาที ซึ่งเท่ากับโควตาขนาดสองคอร์ แผนที่โฆษณาว่ามี 4 vCPU แต่มีโควตาเพียงสองคอร์จะไม่มีทางทำคะแนนได้เท่ากับสี่คอร์ เครื่องมือวัดประสิทธิภาพสามารถระบุข้อจำกัดดังกล่าวได้ โดย VoxelBench จะรายงานโควตา CPU และแจ้งเตือนเมื่อพบ CPU ที่ใช้งานร่วมกันหรือถูกจำกัดความเร็ว ในกรณีที่โฮสต์แสดงจำนวน CPU มากกว่าที่เซิร์ฟเวอร์ได้รับอนุญาตให้ใช้งานจริง
df -hT / มีความสำคัญด้วยเหตุผลอื่น นั่นคือคอลัมน์ Type หากค่าที่อ่านได้คือ overlay แสดงว่าคุณอยู่ภายในคอนเทนเนอร์ และผลลัพธ์ด้านดิสก์ของคุณจะอธิบายถึงพื้นที่จัดเก็บข้อมูลที่อยู่ภายใต้ overlay นั้น ให้จดบันทึกค่านี้ไว้ทันที
การเฝ้าสังเกต Steal time ตลอดเวลา
Steal time คือสัดส่วนเวลาที่ virtual CPU ของคุณต้องรอโดยไม่สมัครใจในขณะที่ hypervisor ไม่ได้จัดสรรเวลาให้ มันเป็นสัญญาณที่มีประโยชน์ในการระบุว่า CPU ไม่ว่างให้ใช้งาน แต่ค่านี้ไม่สามารถแยกแยะได้ว่าเกิดจากเพื่อนบ้านที่ใช้งานหนักหรือเกิดจากการที่ผู้ให้บริการบังคับใช้ CPU quota กับคุณ
vmstat 1 10ให้อ่านคอลัมน์ st ที่อยู่ทางด้านขวา หากมีค่า steal time เกิดขึ้นอย่างต่อเนื่อง แสดงว่า CPU ไม่ว่างให้ guest ใช้งาน แต่ค่าที่สูงกว่า 5% ไม่ได้เป็นเครื่องพิสูจน์ว่า host มีการใช้งานทรัพยากรเกินขีดจำกัด ผู้ให้บริการบางรายอาจแสดงการบังคับใช้ CPU quota ออกมาเป็นค่า steal time โดยเจตนา top จะแสดงตัวเลขเดียวกันกับ %st ในบรรทัด CPU ให้เปิด vmstat 1 ทิ้งไว้ใน SSH session ที่สองในขณะที่คุณทำ benchmark และจดบันทึกค่า steal time ไว้ข้างผลลัพธ์แต่ละรายการ
เริ่มต้นด้วย yabs.sh
yabs.sh (Yet Another Bench Script) เป็นเชลล์สคริปต์ที่รัน fio, iperf3 และ Geekbench แล้วแสดงผลสรุปออกมาในที่เดียว สคริปต์นี้จะใช้ fio และ iperf3 ที่ติดตั้งอยู่ในระบบอยู่แล้ว หรือดาวน์โหลด static binary มาใช้หากยังไม่มีการติดตั้ง ถือเป็นภาษากลางที่ใช้ในการสนทนาเรื่องผลทดสอบ VPS ดังนั้นผลลัพธ์จาก yabs จึงเป็นวิธีที่เร็วที่สุดในการเปรียบเทียบข้อมูลกับผู้อื่น
รูปแบบคำสั่งบรรทัดเดียวของโปรเจกต์นี้คือดังนี้
curl -sL yabs.sh | bashคำสั่งนี้จะส่งเนื้อหาจาก URL ไปยังเชลล์โดยตรง ให้ดาวน์โหลดมาอ่านก่อน แล้วจึงค่อยรัน
curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.shสามารถใส่ flag ต่อท้าย -s -- ได้หากใช้วิธี pipe หรือใส่ต่อท้ายชื่อไฟล์โดยตรงเมื่อรันไฟล์ที่ดาวน์โหลดมาแล้ว flag ที่มีประโยชน์ ได้แก่ -f สำหรับข้ามการทดสอบดิสก์, -i สำหรับข้ามการทดสอบเครือข่าย, -g สำหรับข้าม Geekbench, -r สำหรับจำกัดตำแหน่งทดสอบ iperf3 ให้เหลือเพียง 3 แห่ง, -j สำหรับแสดงผลลัพธ์เป็นรูปแบบ JSON และ -w results.json สำหรับเขียน JSON นั้นลงในไฟล์
bash yabs.sh -r -w yabs-run1.jsonมีสองสิ่งที่ควรทราบก่อนการรันครั้งแรก Geekbench จะอัปโหลดผลการทดสอบของคุณและสร้าง URL สาธารณะบน browser.geekbench.com ซึ่งใครก็ตามที่มีลิงก์นี้จะสามารถอ่านรุ่น CPU และคะแนนของคุณได้ หากต้องการหลีกเลี่ยง ให้ใช้ -g เพื่อข้ามการทดสอบส่วนนี้ไปโดยสิ้นเชิง ประการที่สอง ขั้นตอนการทดสอบ iperf3 จะมีการรับส่งข้อมูลจริงไปยังเซิร์ฟเวอร์ในหลายภูมิภาค ซึ่งจะถูกนับรวมในโควตาแบนด์วิดท์รายเดือนของคุณ บนลิงก์ความเร็ว 1 Gbit/s ขั้นตอนการทดสอบเครือข่ายเต็มรูปแบบอาจใช้ข้อมูลหลายสิบกิกะไบต์ ดังนั้นควรใช้ -r หากคุณมีโควตาจำกัด และใช้ -i หากคุณใช้งานบนลิงก์ที่มีการคิดค่าบริการตามปริมาณการใช้งานจริง
ความหมายของผลลัพธ์จาก yabs
ส่วนของ disk จะรัน fio ด้วยการอ่านและเขียนแบบผสม 50/50 ที่ขนาดบล็อก 4 ขนาด ได้แก่ 4k, 64k, 512k และ 1m โดยจะรายงานค่า IOPS (จำนวนการอ่าน/เขียนต่อวินาที) และแบนด์วิดท์สำหรับแต่ละขนาด แถว 4k คือส่วนที่ควรให้ความสำคัญสำหรับฐานข้อมูล, เมลเซิร์ฟเวอร์ หรือบริการใดๆ ที่มีการเขียนข้อมูลขนาดเล็กจำนวนมาก เนื่องจาก IO ของเซิร์ฟเวอร์ส่วนใหญ่มีขนาดเล็กและกระจัดกระจาย ส่วนแถว 1m คือส่วนสำหรับการสำรองข้อมูลและวิดีโอ ซึ่งเป็นการย้ายข้อมูลปริมาณมากในคราวเดียว
ส่วนของ network จะรัน iperf3 ไปยังเซิร์ฟเวอร์สาธารณะในหลายภูมิภาค ทั้งในทิศทางขาเข้าและขาออกโดยใช้ parallel streams ให้มองว่าตัวเลขที่ต่ำในส่วนนี้เป็นเพียงข้อสงสัยมากกว่าจะเป็นคำตอบที่แน่ชัด เนื่องจากเซิร์ฟเวอร์ iperf3 สาธารณะมีการใช้งานร่วมกันและมักจะมีความหนาแน่นสูง ดังนั้นผลลัพธ์ที่ต่ำอาจเกิดจากฝั่งปลายทางได้
ส่วนของ Geekbench จะแสดงคะแนน single core และ multi core คะแนน single core ช่วยคาดการณ์ความเร็วในการประมวลผลคำขอเดียว, การคอมไพล์งานเดียว หรือการคิวรีเดียว ส่วนคะแนน multi core จะบอกให้ทราบถึงจำนวนคอร์ที่ใช้งานได้จริงเป็นหลัก
Disk: เรียกใช้ fio ด้วยตนเอง
fio (flexible IO tester) คือเครื่องมือที่อยู่เบื้องหลังส่วนการทดสอบดิสก์ของ yabs และการสั่งงานโดยตรงจะทำให้ flag ต่างๆ เริ่มมีความหมายชัดเจนขึ้น
sudo apt update && sudo apt install -y fio sysbench iperf3การทดสอบการอ่านแบบสุ่มขนาด 4k ที่ queue depth 32 บนระบบไฟล์ที่คุณต้องการตรวจสอบจริง:
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 ออกมา ค่า percentile ที่ 99.00th คือตัวเลขที่ควรนำมาอ้างอิง เพราะเป็นระยะเวลาที่คำขอที่ช้าที่สุด 1 รายการใน 100 รายการต้องรอ ค่าเฉลี่ย (average latency) มักจะบดบังอาการกระตุกที่ผู้ใช้งานสัมผัสได้จริง
--direct=1เปิดไฟล์ด้วยO_DIRECTเพื่อให้การอ่านข้าม kernel page cache ไป หากไม่มี flag นี้ การทดสอบรอบที่สองบนไฟล์ขนาด 2G ในเครื่องที่มี RAM 8G จะถูกอ่านจากหน่วยความจำ และ fio จะรายงานค่า IOPS ในระดับล้าน ซึ่งตัวเลขนั้นเป็นจริง แต่เป็นตัวเลขของหน่วยความจำไม่ใช่ดิสก์--ioengine=libaioส่งคำขอแบบอะซิงโครนัส ซึ่งเป็นสิ่งที่ทำให้--iodepth=32สามารถคงจำนวนคำขอที่ค้างอยู่ (in flight) ไว้ได้ 32 รายการ หากใช้ engine แบบซิงโครนัสอย่างpsyncค่า iodepth ที่มากกว่า 1 จะไม่มีผลใดๆ ทำให้คุณวัดได้เพียงทีละหนึ่งคำขอเท่านั้น--time_based --runtime=60ทำงานเป็นเวลาคงที่ 60 วินาทีแทนที่จะกำหนดปริมาณงานที่แน่นอน เพื่อให้ดิสก์ที่เร็วและช้าใช้เวลาทดสอบเท่ากัน ทำให้การเปรียบเทียบมีความยุติธรรม--size=2Gกำหนดขนาดไฟล์ทดสอบ ควรตั้งค่าให้ใหญ่กว่า cache ใดๆ ในเส้นทางข้อมูล และตรวจสอบให้แน่ใจว่ามีพื้นที่ว่างเพียงพอก่อนเริ่ม
การเขียนแบบสุ่มใช้คำสั่งเดียวกันโดยเปลี่ยนเป็น --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 ประเภทของพื้นที่จัดเก็บข้อมูลที่คุณใช้งานอยู่ส่งผลต่อผลลัพธ์มากกว่าการปรับ flag ใดๆ และความแตกต่างดังกล่าวได้อธิบายไว้ใน ความแตกต่างระหว่างพื้นที่จัดเก็บข้อมูลแบบ NVMe และ SATA SSD บน VPS
เมื่อ fio หยุดทำงานพร้อมข้อความ Unknown error -1
Direct IO ไม่สามารถใช้งานได้กับทุกระบบไฟล์ ดังนั้นเมื่อ fio ล้มเหลวตั้งแต่คำขอแรกโดยมีการตั้งค่า --direct=1 ไว้ Direct IO คือสิ่งแรกที่ต้องตรวจสอบ ความผิดพลาดอาจมีลักษณะดังนี้:
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 ซึ่งเป็นระบบไฟล์ที่ Docker กำหนดให้คอนเทนเนอร์โดยค่าเริ่มต้นนั้น ไม่ใช่สาเหตุของปัญหาด้วยตัวมันเอง overlayfs จะส่งผ่าน O_DIRECT ไปยังระบบไฟล์เบื้องล่างและจะปฏิเสธก็ต่อเมื่อระบบไฟล์นั้นไม่รองรับ Direct IO ดังนั้น --direct=1 --ioengine=libaio จึงใช้งานได้บน overlay ที่อยู่บน ext4 หรือ xfs เมื่อระบบไฟล์ภายใต้ไฟล์ทดสอบไม่สามารถทำ Direct IO ได้จริง fio มักจะแจ้งเตือนขณะเปิดไฟล์ว่า: fio: looks like your file system does not support direct=1/buffered=0 ในกรณีนี้ ให้ชี้ --filename ไปยัง path บนที่จัดเก็บข้อมูลในเครื่องจริง เช่น 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 ถูกติดตั้งและ flag ต่างๆ ถูกต้องเท่านั้น ห้ามนำไปอ้างอิงเป็นผลลัพธ์ของดิสก์โดยเด็ดขาด
เหตุใด dd จึงไม่ใช่เครื่องมือวัดประสิทธิภาพดิสก์
dd ปรากฏอยู่ในกระทู้เกี่ยวกับ VPS จำนวนมาก และมันตอบคำถามได้เพียงแง่มุมเดียวเท่านั้น
dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtestคำสั่งดังกล่าววัดปริมาณงานเขียนแบบลำดับ (sequential write throughput) ด้วยเธรดเดียวและคำขอเดียวที่กำลังประมวลผลอยู่ มันเป็นการตรวจสอบความพร้อมใช้งานเบื้องต้นที่สมเหตุสมผล แต่ไม่ได้บอกอะไรเกี่ยวกับประสิทธิภาพการอ่านเขียนแบบสุ่ม (random IO) และไม่ได้บอกว่าจะเกิดอะไรขึ้นเมื่อมีคำขอ 32 รายการเข้ามาพร้อมกัน หากละเว้น oflag=direct ข้อมูลที่เขียนจะผ่าน page cache แต่ conv=fdatasync ยังคงบังคับให้ข้อมูลขาออกถูกเขียนลงสื่อบันทึกข้อมูลก่อนที่คำสั่งจะเสร็จสิ้น หากละเว้นส่วนนี้ไปด้วย ผลลัพธ์ที่ได้จะเป็นเพียงการวัดความเร็วที่ kernel ของคุณยอมรับการเขียนข้อมูลลงหน่วยความจำ ซึ่งเป็นเหตุผลว่าทำไมตัวเลข 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 ให้รันแบบ single threaded ก่อน นี่คือตัวเลขที่ตัดสินว่าคำขอ PHP หนึ่งรายการหรือการคอมไพล์งานหนึ่งชิ้นจะเสร็จสิ้นเร็วเพียงใด และเป็นค่าที่แปรผันมากที่สุดระหว่างโฮสต์ที่มีราคาเท่ากัน จากนั้นให้รันด้วยทุกเธรด ซึ่งจะแสดงให้เห็นว่า throughput มีการขยายตัวอย่างไรใน vCPU ที่คุณได้รับจัดสรร
ต้องมีความชัดเจนว่าสิ่งนี้วัดค่าอะไร: sysbench cpu จะใช้วิธีการหารทดลองเพื่อหาจำนวนเฉพาะซ้ำๆ สำหรับตัวเลขแต่ละตัวที่นำมาทดสอบ มันจะหาค่ารากที่สองแบบ double precision จากนั้นทดสอบตัวหารด้วยการทำ modulo ของจำนวนเต็ม 64 บิต โดยเปรียบเทียบตัวหารแต่ละตัวกับขีดจำกัดของเลขทศนิยมนั้น ดังนั้นมันจึงเป็นการผสมผสานระหว่างการทำงานของจำนวนเต็มและเลขทศนิยม มันไม่ได้สร้างภาระให้กับ memory bandwidth, vector units หรือ cache ในรูปแบบที่ใกล้เคียงกับภาระงานจริง ดังนั้นมันจึงเหมาะสำหรับการจัดอันดับโฮสต์สองแห่ง แต่ไม่เหมาะสำหรับการคาดการณ์ว่าแอปพลิเคชันของคุณจะทำงานอย่างไร
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 ตัวเลขจะลดลงอย่างมาก เนื่องจากคุณต้องเสียค่า overhead ต่อการดำเนินการเพิ่มขึ้นเป็นพันเท่า ผลลัพธ์ที่ได้จึงกลายเป็นการวัดต้นทุนของลูปแทนที่จะเป็นแบนด์วิดท์ของหน่วยความจำ นี่คือ flag ที่มักถูกตั้งค่าไม่ตรงกันมากที่สุดในผลการทดสอบหน่วยความจำที่เผยแพร่ทั่วไป
เครือข่าย: iperf3
วิธีที่ตรงไปตรงมาที่สุดในการทดสอบปริมาณข้อมูล (throughput) คือการทดสอบกับเครื่องอีกเครื่องที่คุณควบคุมได้ เพราะคุณจะทราบสถานะการทำงานของทั้งสองฝั่ง
ที่ฝั่งปลายทาง:
iperf3 -sคำสั่งนี้จะเปิดการรับฟังที่ TCP พอร์ต 5201 ให้เปิดพอร์ตนี้เฉพาะสำหรับที่อยู่ IP ที่คุณใช้ทดสอบเท่านั้น และปิดพอร์ตทันทีเมื่อเสร็จสิ้น กฎพื้นฐานของ ufw firewall บน VPS อธิบายไวยากรณ์ที่เกี่ยวข้องไว้แล้ว
จาก 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 หนึ่งรายการสามารถรองรับข้อมูลที่ยังไม่ได้รับการตอบรับ (unacknowledged data) ได้จำกัดตามขนาดของหน้าต่าง (window size) ดังนั้นขีดจำกัดจึงอยู่ที่ขนาดหน้าต่างหารด้วยเวลาในการรับส่งข้อมูลไปกลับ (round trip time) หากมีความหน่วง (latency) ที่ 80 ms และขนาดหน้าต่าง 4 MB ขีดจำกัดจะอยู่ที่ประมาณ 400 Mbit/s ไม่ว่าลิงก์จริงจะมีความเร็วเท่าใดก็ตาม ตัวเลขจากการทดสอบสตรีมเดี่ยวจะบอกความเร็วที่คุณได้รับในการดาวน์โหลดไฟล์เดียว ส่วนตัวเลขจากการทดสอบแบบขนานจะบอกถึงความจุรวมของลิงก์นั้น
โปรดตรวจสอบโควตาแบนด์วิดท์ของคุณในระหว่างการทดสอบนี้ การทดสอบที่ความเร็ว 1 Gbit/s เป็นเวลา 30 วินาที จะใช้ข้อมูลประมาณ 3.75 GB และคุณจะต้องทดสอบซ้ำหลายครั้งในแต่ละทิศทาง
ตัวเลขมาตรฐานและวิธีการอ่านค่าของคุณ
ข้อมูลเบื้องหลังแผนภูมินี้
[
{
"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 volume ภายในเครื่องที่ปรากฏในผลการทดสอบมักจะมีค่า 4k random read IOPS อยู่ที่ประมาณ 180,000 ส่วน SATA SSD ภายในเครื่องจะอยู่ที่ประมาณ 90,000 สำหรับ block storage ที่เชื่อมต่อผ่านเครือข่าย ซึ่งทุกคำขอจะต้องเดินทางผ่านเครือข่ายก่อนจะถึงดิสก์ จะมีค่าอยู่ที่ประมาณ 12,000 และสำหรับฮาร์ดดิสก์แบบจานหมุนจะทำได้ประมาณ 180 เนื่องจากต้องมีการเคลื่อนที่ของหัวอ่านในทุกคำขอแบบสุ่ม
ตัวเลขเหล่านี้เป็นค่ามาตรฐานที่เผยแพร่สำหรับที่เก็บข้อมูลแต่ละประเภท ไม่ใช่การวัดผลจากโฮสต์เพียงเครื่องเดียว ให้ใช้ตัวเลขเหล่านี้เพื่อจุดประสงค์เดียวคือ ตรวจสอบว่าผลลัพธ์ของคุณอยู่ในระดับที่เหมาะสมหรือไม่ หากแพ็กเกจที่ขายในฐานะ NVMe ให้ผลการทดสอบ 4k IOPS เพียงหลักพันต้นๆ ก่อนอื่นให้ยืนยันว่าเปิดใช้งาน --direct=1 แล้ว หากเปิดใช้งานแล้ว ให้ตรวจสอบขีดจำกัด IOPS และ burst credits ของแพ็กเกจนั้น รวมถึงตรวจสอบการแย่งชิงทรัพยากรของที่เก็บข้อมูลและฮาร์ดแวร์ที่ระบุไว้ด้วย
เหตุใดการทดสอบเพียงครั้งเดียวจึงไม่ใช่การวัดประสิทธิภาพ (Benchmark)
ผลลัพธ์เพียงครั้งเดียวเป็นเพียงภาพสะท้อนของช่วงเวลาหนึ่งนาทีบนเครื่องที่ใช้งานร่วมกัน ให้ถือว่ามันเป็นเพียงกลุ่มตัวอย่างเดียวเท่านั้น
- ดำเนินการทดสอบทุกรายการอย่างน้อย 5 ครั้ง โดยกระจายในช่วงเวลาที่ต่างกันและอย่างน้อย 2 วันที่ต่างกัน ให้เก็บค่ามัธยฐาน (median) และค่าการกระจายตัว (spread) ไว้ ผลลัพธ์ที่เผยแพร่โดยไม่มีค่าการกระจายตัวถือเป็นตัวเลขทางการตลาด
- บันทึกค่า steal time ควบคู่ไปกับการทดสอบแต่ละครั้ง ให้เก็บผลการทดสอบที่
stมีค่าสูงไว้ และตรวจสอบว่าค่าดังกล่าวสะท้อนถึงการแย่งชิงทรัพยากร (contention) หรือโควตา CPU ของแผนบริการนั้นๆ การตัดผลลัพธ์เหล่านี้ทิ้งอาจทำให้คุณมองไม่เห็นประสิทธิภาพที่คุณได้รับจริง - ดำเนินการทดสอบดิสก์ด้วยระยะเวลา 2 รูปแบบ แผนบริการจำนวนมากให้โควตา IOPS แบบ burst ซึ่งจะค่อยๆ ฟื้นคืนมา แต่ทั้งการรัน fio เป็นเวลา 60 วินาที หรือ
--runtime=600ไม่สามารถรับประกันได้ว่าคุณได้วัดค่าประสิทธิภาพขั้นต่ำ (floor) แล้ว ตัวอย่างเช่น AWS gp2 สามารถรักษาประสิทธิภาพที่ 3,000 IOPS ได้อย่างน้อย 30 นาทีจากยอดคงเหลือเต็ม ดังนั้นการทดสอบทั้งสองแบบอาจเป็นการวัดประสิทธิภาพในช่วง burst เท่านั้น ให้ตรวจสอบรูปแบบการให้เครดิตของผู้ให้บริการและตรวจสอบยอดคงเหลือของเครดิตก่อนที่จะสรุปผลลัพธ์ว่าเป็นประสิทธิภาพที่ยั่งยืน (sustained performance) - ตรวจสอบว่าไม่มีกระบวนการอื่นทำงานอยู่ การที่
unattended-upgradesเริ่มการทำธุรกรรม apt ระหว่างการทดสอบ CPU จะทำให้คุณเสียคะแนนจริง และการทำps -e -o comm= | grep -E 'apt|dpkg'ก่อนการทดสอบแต่ละครั้งจะใช้เวลาหนึ่งวินาที - เปลี่ยนตัวแปรทีละหนึ่งรายการเท่านั้น เวอร์ชันของเครื่องมือ ขนาดบล็อก หรือจำนวนเธรดที่ต่างกัน จะให้ตัวเลขที่ไม่สามารถนำมาเปรียบเทียบกันได้ ไม่ว่าตัวเลขเหล่านั้นจะดูใกล้เคียงกันเพียงใดก็ตาม
เมื่อคุณเปรียบเทียบผู้ให้บริการสองราย ให้ทำการทดสอบในชั่วโมงเดียวกันของวันเดียวกัน มิฉะนั้นสิ่งที่คุณวัดได้จะเป็นเพียงผลกระทบจากช่วงเวลาของวันเท่านั้น
ทดสอบประสิทธิภาพด้วยภาระงานจริงของคุณเป็นลำดับสุดท้าย
เครื่องมือสังเคราะห์ทำหน้าที่จัดอันดับเครื่องคอมพิวเตอร์ แต่มีเพียงภาระงานของคุณเท่านั้นที่จะบอกได้ว่าเครื่องนั้นเพียงพอหรือไม่ ให้จับเวลาสิ่งที่คุณทำจริง
time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgzกระบวนการนั้นจะบีบอัดข้อมูลขนาดไม่กี่ร้อยเมกะไบต์ จึงเป็นการใช้งานทั้ง CPU และดิสก์ร่วมกัน และผลลัพธ์จะเปลี่ยนแปลงไปเมื่อประสิทธิภาพของส่วนประกอบใดส่วนประกอบหนึ่งเปลี่ยนไป คำเตือน Removing leading / from member names ถือเป็นเรื่องปกติ วิธีที่ดีกว่าคือการจับเวลาการ build ของคุณเอง, query ที่ช้าที่สุดของคุณ หรือการเรนเดอร์หน้าเว็บของคุณเอง หากการ build ใช้เวลา 4 นาทีบนโฮสต์หนึ่งและ 7 นาทีบนอีกโฮสต์หนึ่ง นั่นก็ถือว่าตัดสินคำถามได้แล้ว ไม่ว่า Geekbench จะประเมินไว้อย่างไรก็ตาม นี่คือการวัดผลที่จะบอกคุณด้วยว่าเมื่อใดที่การเพิ่มสเปกเครื่องไม่คุ้มค่ากับการจ่ายเงินเพิ่ม ซึ่งเป็นสิ่งที่ควรทราบก่อนที่คุณจะอ่าน ราคา VPS ที่แท้จริงต่อเดือน หรือย้ายภาระงานไปยัง เซิร์ฟเวอร์เฉพาะ (dedicated server)
FAQ
ทำไมผลการทดสอบ benchmark ถึงไม่เท่ากันในแต่ละครั้งที่รัน?
VPS ใช้งาน CPU, พื้นที่จัดเก็บข้อมูล และเครือข่ายร่วมกับผู้เช่ารายอื่น ผลลัพธ์จึงขึ้นอยู่กับกิจกรรมของผู้อื่นในขณะนั้น ให้รัน vmstat 1 ระหว่างการทดสอบและดูที่คอลัมน์ st ค่า steal time ที่เกิดขึ้นต่อเนื่องจะบันทึกเวลา CPU ที่ไม่สามารถใช้งานได้ ซึ่งอาจสะท้อนถึงการที่ผู้ให้บริการจำกัดการใช้งาน CPU ตามแพ็กเกจหรือเกิดการแย่งชิงทรัพยากรบนโฮสต์ หากค่าสูงกว่า 5% ไม่สามารถสรุปสาเหตุที่แน่ชัดได้ คำตอบคือการใช้วิธีการทดสอบที่ถูกต้องแทนการปรับแต่ง ให้รันการทดสอบแต่ละรายการอย่างน้อย 5 ครั้งในช่วงเวลาที่ต่างกัน แล้วรายงานค่ามัธยฐานพร้อมกับช่วงความต่างของข้อมูล
ทำไม fio ถึงรายงานค่า IOPS สูงถึงหลักล้าน?
เกือบทุกครั้งเกิดจากการลืมใส่ --direct=1 หากไม่มีแฟล็กนี้ fio จะอ่านผ่าน kernel page cache ทำให้หลังจากรอบแรก ไฟล์ทดสอบขนาด 2G จะถูกอ่านจาก RAM และคุณกำลังวัดความเร็วของหน่วยความจำแทน ให้เพิ่ม --direct=1 และกำหนดขนาดไฟล์ทดสอบให้ใหญ่กว่า cache ทุกจุดในเส้นทาง หาก --direct=1 ล้มเหลว ให้รัน df -hT . เพื่อตรวจสอบว่าไฟล์ทดสอบวางอยู่บนอะไร ประเภทของ overlay ไม่ใช่ปัญหาในตัวมันเอง เพราะ overlayfs จะส่งผ่าน O_DIRECT ไปยังพื้นที่จัดเก็บข้อมูลด้านล่างโดยตรง ให้ย้ายไฟล์ทดสอบไปยังพื้นที่จัดเก็บข้อมูลในเครื่องจริงก็ต่อเมื่อระบบไฟล์ด้านล่างปฏิเสธการทำ direct IO เท่านั้น
yabs.sh เพียงพอสำหรับการทดสอบหรือไม่?
สำหรับการตรวจสอบเบื้องต้นถือว่าเพียงพอ มันรัน fio ที่ขนาดบล็อก 4 รูปแบบ, iperf3 ทั้งสองทิศทาง และ Geekbench พร้อมแสดงสรุปผลที่ผู้อื่นอ่านเข้าใจได้ง่าย แต่จะไม่เพียงพอเมื่อคุณต้องการทราบสาเหตุของตัวเลขนั้นๆ เพราะคุณไม่สามารถปรับเปลี่ยนแฟล็กในแต่ละการทดสอบได้ เมื่อผลลัพธ์จาก yabs ดูผิดปกติ ให้ทดสอบซ้ำด้วย fio หรือ sysbench โดยตรงและปรับเปลี่ยนทีละแฟล็ก
ตัวเลขใดที่บ่งบอกถึงประสิทธิภาพการใช้งานจริงของแอปพลิเคชันได้ดีที่สุด?
ความเร็ว CPU แบบ single core และค่า latency ของการอ่านแบบสุ่มขนาด 4k ตามลำดับ สำหรับภาระงานส่วนใหญ่ของเว็บและฐานข้อมูล ตัวเลข throughput ดูน่าประทับใจแต่แทบไม่ได้เป็นตัวตัดสินสิ่งใด เพราะคำขอทั่วไปมีขนาดเล็ก ให้ดูค่า 99th percentile จากบล็อก clat percentiles ของ fio แทนค่าเฉลี่ย เนื่องจากคำขอที่ช้าเพียง 1 ใน 100 คือสิ่งที่ผู้ใช้งานจะรู้สึกได้จริง
จำเป็นต้องติดตั้งอะไรก่อนเริ่มทำ benchmark หรือไม่?
fio, sysbench และ iperf3 มีอยู่ในคลังซอฟต์แวร์ของ Ubuntu และ Debian: sudo apt install -y fio sysbench iperf3 ส่วน yabs.sh รันบน Bash และต้องการ curl หรือ wget สำหรับการดาวน์โหลด รวมถึง tar เพื่อแตกไฟล์ Geekbench หากไม่มี tar ระบบจะข้ามการทดสอบ Geekbench ไป มันจะใช้ fio และ iperf3 ที่ติดตั้งอยู่ในระบบ หรือดาวน์โหลดไฟล์ binary แบบ static มาใช้หากไม่พบ ให้ลบไฟล์ทดสอบทั้งหมดเมื่อเสร็จสิ้น เพราะไฟล์ fio ขนาด 2G ที่ทิ้งไว้บนดิสก์ขนาด 20G อาจกลายเป็นสาเหตุที่ทำให้ดิสก์เต็มในอีกหลายสัปดาห์ถัดมา