ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

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

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

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

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

สิ่งที่ต้องเตรียม

  • สิทธิ์ 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/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security