Load Average สูงผิดปกติ: ไล่หาสาเหตุทีละชั้นบน Linux

อ่านค่า Load Average ให้ถูกความหมาย แล้วไล่หาว่าคอขวดอยู่ที่ CPU, ดิสก์ หรือหน่วยความจำ ด้วย top, vmstat, iostat และ pidstat

โดย ทีมงาน THAI DATA CLOUD อัปเดต อ่าน 8 นาที เข้าชม 5 ครั้ง

แชร์FacebookXLINELinkedIn
Load Average — Load Average สูงผิดปกติ: ไล่หาสาเหตุทีละชั้นบน Linux
Load Average สูงผิดปกติ: ไล่หาสาเหตุทีละชั้นบน Linux

คำตอบสั้น ๆ: อ่านค่า Load Average ให้ถูกความหมาย แล้วไล่หาว่าคอขวดอยู่ที่ CPU, ดิสก์ หรือหน่วยความจำ ด้วย top, vmstat, iostat และ pidstat

คู่มือนี้อธิบาย Load Average ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย

เมื่อเว็บช้าหรือเซิร์ฟเวอร์ตอบสนองหน่วง สิ่งแรกที่ทุกคนดูคือ Load Average แต่ตัวเลขนี้ถูกเข้าใจผิดบ่อยที่สุดในบรรดาค่าทั้งหมดบน Linux เพราะมันไม่ได้วัดแค่ CPU อย่างที่หลายคนคิด

คู่มือนี้อธิบายความหมายที่ถูกต้องของ Load Average แล้วไล่หาสาเหตุทีละชั้นตามลำดับที่ควรตรวจจริง จาก CPU ไปดิสก์ ไปหน่วยความจำ และไปที่เครือข่าย พร้อมคำสั่งที่ใช้ได้ทั้งบน Ubuntu, Debian, AlmaLinux และ Rocky Linux

สิ่งที่ต้องเตรียม (Load Average)

  • สิทธิ์ SSH เข้าเซิร์ฟเวอร์ และสิทธิ์ sudo
  • ติดตั้งชุดเครื่องมือวัดผล หากยังไม่มี
# Ubuntu / Debian
sudo apt install -y sysstat procps

# AlmaLinux / Rocky Linux
sudo dnf install -y sysstat procps-ng

ขั้นตอนที่ 1: อ่าน Load Average ให้ถูกความหมาย

uptime
cat /proc/loadavg
nproc

ตัวเลขสามตัวคือค่าเฉลี่ยของ 1, 5 และ 15 นาทีที่ผ่านมา และมันนับ "จำนวนโปรเซสที่กำลังทำงานหรือกำลังรอ" ไม่ใช่เปอร์เซ็นต์ CPU สิ่งที่หลายคนพลาดคือโปรเซสที่รออ่านเขียนดิสก์อยู่ก็ถูกนับรวมด้วย

เทียบกับจำนวนคอร์เสมอ ค่าที่ได้จาก nproc คือเพดานคร่าว ๆ

  • เครื่อง 4 คอร์ Load 4.0 หมายถึงใช้เต็มพอดี ยังไม่ถือว่าผิดปกติ
  • เครื่อง 4 คอร์ Load 12.0 หมายถึงมีงานรอคิวมากกว่าที่ทำไหวสามเท่า
  • เครื่อง 4 คอร์ Load 1.0 แต่เว็บช้า แปลว่าคอขวดไม่ได้อยู่ที่ปริมาณงาน ให้ไปดูข้อ 4 และ 5

ดูแนวโน้มด้วย ถ้าค่า 1 นาทีสูงกว่า 15 นาทีมาก แปลว่าปัญหาเพิ่งเกิดและกำลังแย่ลง ถ้ากลับกันแปลว่าผ่านจุดพีคมาแล้ว

ขั้นตอนที่ 2: แยกให้ออกว่าเป็น CPU หรือการรอดิสก์

นี่คือทางแยกสำคัญที่สุด ใช้ vmstat เก็บตัวอย่างทุกวินาที

vmstat 1 10

ดูสามคอลัมน์นี้

  • r จำนวนโปรเซสที่พร้อมทำงานและรอ CPU ถ้าค่านี้สูงกว่าจำนวนคอร์ต่อเนื่อง แปลว่าคอขวดคือ CPU
  • b จำนวนโปรเซสที่ติดรอ I/O ถ้าค่านี้สูง แปลว่าคอขวดคือดิสก์
  • wa เปอร์เซ็นต์เวลาที่ CPU ว่างเพราะรอ I/O ค่าเกิน 20 ต่อเนื่องคือสัญญาณว่าดิสก์ตามไม่ทัน

ในคอลัมน์ฝั่ง cpu ให้ดู us (งานของผู้ใช้) และ sy (งานของเคอร์เนล) ประกอบ ถ้า sy สูงผิดปกติมักเกี่ยวกับเครือข่าย ระบบไฟล์ หรือ Container จำนวนมาก

ขั้นตอนที่ 3: หาโปรเซสที่กิน CPU

top -o %CPU

ใน top กด 1 เพื่อแยกดูรายคอร์ กด M เพื่อเรียงตามการใช้หน่วยความจำ และกด c เพื่อดูคำสั่งเต็มพร้อมพารามิเตอร์ ซึ่งมักเป็นตัวบอกว่าใครเรียกงานนั้น

ถ้าอยากได้ภาพเฉลี่ยแทนภาพวินาทีเดียว ใช้ pidstat

pidstat -u 2 5

สำหรับเว็บเซิร์ฟเวอร์ ให้ดูว่าเป็น php-fpm, mysqld หรือ nginx โดยปกติ php-fpm หลายตัวกิน CPU เต็มพร้อมกันมักแปลว่ามีสคริปต์ที่ช้าหรือมีทราฟฟิกจากบอต

ขั้นตอนที่ 4: ตรวจดิสก์

iostat -xz 2 5

ดูคอลัมน์ %util ซึ่งบอกว่าดิสก์ยุ่งกี่เปอร์เซ็นต์ของเวลา และ await ซึ่งคือเวลาเฉลี่ยที่คำขอหนึ่งต้องรอ หน่วยเป็นมิลลิวินาที บน SSD ค่า await ควรอยู่หลักหน่วย ถ้าขึ้นไปหลักสิบหรือร้อยแปลว่าดิสก์เป็นคอขวดชัดเจน

หาว่าโปรเซสไหนอ่านเขียนหนัก

sudo pidstat -d 2 5
sudo iotop -oPa

สาเหตุที่พบบ่อยคือ งานสำรองข้อมูลที่ทับกับเวลาทำการ การ import ฐานข้อมูลขนาดใหญ่ ไฟล์ Log ที่เขียนถี่เกินไป และ MySQL ที่ไม่มี Index จนต้องอ่านทั้งตาราง

ขั้นตอนที่ 5: ตรวจหน่วยความจำและ Swap

free -h
vmstat 1 5

ในผลของ vmstat ให้ดูคอลัมน์ si และ so ซึ่งคือการสลับหน้าหน่วยความจำเข้าออกจาก Swap ถ้าค่านี้ไม่ใช่ศูนย์ต่อเนื่อง เครื่องกำลังขาดหน่วยความจำ และอาการที่เห็นคือช้าทั้งระบบพร้อมกับ Load พุ่ง

ตรวจว่าเคยมีโปรเซสถูกระบบฆ่าทิ้งเพราะหน่วยความจำหมดหรือไม่

sudo dmesg -T | grep -i -E 'out of memory|oom-kill'
sudo journalctl -k | grep -i oom

หน่วยความจำที่แสดงว่าถูกใช้ไปกับ buff/cache ไม่ใช่ปัญหา ระบบจะคืนให้เองเมื่อโปรแกรมต้องการ ให้ดูที่คอลัมน์ available เป็นหลัก

ขั้นตอนที่ 6: ตรวจจำนวนการเชื่อมต่อ

ss -s
ss -tn state established | wc -l
ss -tn state established '( dport = :443 or sport = :443 )' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head

คำสั่งสุดท้ายจัดอันดับ IP ที่เชื่อมต่อเข้ามามากที่สุด ถ้ามี IP เดียวเชื่อมต่อค้างหลายร้อยการเชื่อมต่อ มักเป็นบอตหรือการสแกน ใช้ร่วมกับ Log ของเว็บเซิร์ฟเวอร์เพื่อยืนยัน

sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

ขั้นตอนที่ 7: สรุปให้เป็นข้อสรุปเดียว

เมื่อเก็บข้อมูลครบ ให้สรุปตามตารางง่าย ๆ นี้

  • r สูง, wa ต่ำ, %util ต่ำ ⟶ คอขวดคือ CPU ให้เพิ่มคอร์ หรือหาสคริปต์ที่กินเวลาประมวลผล
  • b สูง, wa สูง, await สูง ⟶ คอขวดคือดิสก์ ให้ย้ายไป SSD ที่เร็วขึ้น เลื่อนเวลางานสำรองข้อมูล หรือแก้ Query ที่อ่านทั้งตาราง
  • si/so ไม่เป็นศูนย์ ⟶ หน่วยความจำไม่พอ ให้เพิ่ม RAM หรือลดจำนวน Worker ของ PHP-FPM และ MySQL
  • ทุกอย่างปกติแต่ช้า ⟶ มักเป็นปัญหาปลายทาง เช่น API ภายนอกที่ตอบช้า หรือ DNS ที่หมดเวลา

ปัญหาที่พบบ่อย

Load สูงแต่ CPU ว่าง

นี่คือกรณีคลาสสิกของการรอ I/O โปรเซสที่อยู่ในสถานะ D (uninterruptible sleep) ถูกนับเข้า Load ด้วย ดูรายชื่อได้ด้วย ps -eo state,pid,comm | grep '^D'

ตัวเลขพุ่งเป็นช่วง ๆ ทุกคืน

ตรวจงานตามเวลาก่อนเสมอ ด้วย systemctl list-timers และ sudo crontab -l งานสำรองข้อมูล การสแกนไวรัส และ updatedb คือสามตัวที่ทำให้ดิสก์ตันเป็นเวลาเดิมทุกคืน

เห็น kworker หรือ ksoftirqd กิน CPU

เป็นงานของเคอร์เนล มักเกี่ยวกับปริมาณแพ็กเก็ตเครือข่ายที่สูงมากหรืออุปกรณ์ที่มีปัญหา ตรวจทราฟฟิกด้วย ss -s และดู dmesg -T ว่ามีข้อความผิดพลาดของอุปกรณ์หรือไม่

อยากดูย้อนหลังว่าเมื่อคืนเกิดอะไรขึ้น

เปิดการเก็บสถิติของ sysstat ไว้ล่วงหน้า แล้วเรียกดูย้อนหลังได้ด้วย sar -u สำหรับ CPU, sar -d สำหรับดิสก์ และ sar -r สำหรับหน่วยความจำ บน Ubuntu ต้องเปิดใน /etc/default/sysstat ก่อน

หากไล่แล้วยังไม่พบสาเหตุ ทีมวิศวกร THAI DATA CLOUD ช่วยตรวจสอบให้ได้ ติดต่อที่ https://thaidata.cloud/contact/

สรุปขั้นตอน Load Average

ทบทวน Load Average ทั้งหมดตามลำดับ ก่อนนำไปใช้กับระบบจริง

  1. อ่าน Load Average ให้ถูกความหมาย
  2. แยกให้ออกว่าเป็น CPU หรือการรอดิสก์
  3. หาโปรเซสที่กิน CPU
  4. ตรวจดิสก์
  5. ตรวจหน่วยความจำและ Swap
  6. ตรวจจำนวนการเชื่อมต่อ
  7. สรุปให้เป็นข้อสรุปเดียว

เมื่อทำครบทุกข้อแล้ว Load Average จะพร้อมใช้งาน หากผลลัพธ์ไม่เป็นไปตามที่คาด ให้ย้อนกลับไปดูหัวข้อปัญหาที่พบบ่อยด้านบน ซึ่งรวบรวมกรณีที่พบจริงจากการใช้งาน Load Average ไว้แล้ว

อ่านเพิ่มเติมเกี่ยวกับ Load Average

แชร์FacebookXLINELinkedIn

มีคำถามเรื่องบริการ? ติดต่อทีมงาน