Sổ tay kỹ thuật

Load cao, máy chậm – khoanh vùng CPU, RAM, I/O, OOM

troubleshooting#linux#performance#troubleshooting· cập nhật 2026-11-06

Dùng khi server chậm hoặc load average cao, để xác định nghẽn CPU, RAM/swap, đĩa hay process bị OOM killer giết.

Sửa trang này
Mục lục

Triệu chứng chính: uptime báo load average cao hơn nhiều so với số CPU, SSH vào chậm, app timeout, hoặc process tự biến mất (log kernel có Out of memory: Killed process).

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Load cao, %us/%sy gần 100% Process ăn CPU (vòng lặp, regex nặng, GC) top/pidstat -u 1 tìm PID; profile hoặc giới hạn CPUQuota=
Load cao nhưng CPU idle, wa cao Nghẽn đĩa: process ở trạng thái D cũng tính vào load iostat -xz 1 xem %util, await; tìm process bằng pidstat -d 1 / iotop
si/so trong vmstat khác 0 liên tục Thiếu RAM, đang swap Tìm process ăn RAM, thêm RAM, giới hạn MemoryMax=
Process biến mất, exit code 137 OOM killer (hoặc container vượt memory limit) journalctl -k -g 'Out of memory', tăng RAM/limit, sửa leak
st (steal) cao trên VM Hypervisor chia CPU cho VM khác Báo nhà cung cấp, đổi instance
free thấy free gần 0 Thường bình thường: RAM dùng làm page cache Xem cột available, không phải free
Nhiều process D không chết được NFS treo, đĩa lỗi dmesg -T, kiểm tra mount NFS và SMART
sar báo Cannot open /var/log/sysstat/... sysstat chưa bật thu thập apt install sysstat, bật ENABLED="true" trong /etc/default/sysstat, systemctl enable --now sysstat

Các bước khoanh vùng

flowchart TD A["uptime: load cao"] --> B["vmstat 1"] B -->|"r lớn hơn số CPU, us/sy cao"| C["CPU: top, pidstat -u"] B -->|"b lớn, wa cao"| D["I/O: iostat -xz, pidstat -d"] B -->|"si/so khác 0"| E["RAM: free -h, ps theo RSS"] E --> F["OOM? journalctl -k"] B -->|"st cao"| G["VM bị steal CPU"]

Quy trình 60 giây (theo thứ tự):

uptime                          # load 1/5/15 phút; so với nproc
dmesg -T | tail -20             # OOM, lỗi đĩa, NIC
vmstat 1 5                      # r, b, si, so, us, sy, wa, st
mpstat -P ALL 1 3               # có CPU nào 100% một mình? (app đơn luồng, IRQ)
pidstat 1 3                     # CPU theo process
iostat -xz 1 3                  # %util, r_await/w_await, aqu-sz theo đĩa
free -h                         # nhìn cột available
sar -n DEV 1 3                  # throughput NIC
top                             # nhấn 1: từng CPU, M: sort RAM, P: sort CPU

mpstat, pidstat, iostat, sar nằm trong gói sysstat.

Đọc vmstat

Cột Ý nghĩa Đáng lo khi
r Process chờ CPU Liên tục lớn hơn số CPU
b Process chờ I/O (trạng thái D) Liên tục > 0
si / so Swap in/out (KB/s) Khác 0 liên tục
us / sy CPU user / kernel sy cao bất thường: syscall, IRQ, lock
wa CPU rảnh nhưng chờ I/O Cao kèm b > 0
st CPU bị hypervisor lấy > vài % kéo dài

Tìm thủ phạm

ps -eo pid,ppid,user,%cpu,%mem,rss,stat,cmd --sort=-%cpu | head
ps -eo pid,user,rss,cmd --sort=-rss | head              # RSS theo KB
ps -eo stat,pid,cmd | awk '$1 ~ /^D/'                   # process bị kẹt I/O
cat /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io   # PSI: % thời gian bị nghẽn
systemd-cgtop                                           # theo service/container

OOM killer

journalctl -k -g 'Out of memory|oom-kill' --since today
dmesg -T | grep -iE 'killed process|oom'
cat /proc/<pid>/oom_score                               # điểm càng cao càng dễ bị chọn

Cấu hình đúng

Bảo vệ service quan trọng (trên Ubuntu unit SSH tên là ssh.service) và giới hạn service dễ phình to bằng systemd (drop-in qua systemctl edit):

/etc/systemd/system/ssh.service.d/oom.conf
[Service]
OOMScoreAdjust=-900
/etc/systemd/system/netcollector.service.d/limits.conf
[Service]
MemoryHigh=400M
MemoryMax=512M
CPUQuota=100%

Đừng đặt vm.overcommit_memory=2 hay tắt OOM killer để "hết bị kill": máy sẽ treo thay vì mất một process. Sửa gốc: leak, limit, hoặc thêm RAM.

Kiểm tra nhanh

nproc; uptime
vmstat 1 5
iostat -xz 1 3
free -h; swapon --show
journalctl -k -p warning -b --no-pager | tail -30

Xem thêm: namespaces và cgroups, systemd service.