Optimization

Chẩn đoán nghẽn CPU, RAM, I/O trên VPS Linux

VPS chạy chậm dù bảng thông số vẫn còn dư địa? Bạn nhìn vào top thấy %CPU chưa cao, RAM chưa đầy, nhưng website thì trễ, SSH thì lag. Vấn đề gần như chắc chắn nằm ở một trong ba cổ chai: CPU chờ tính toán, RAM bị swap, hoặc I/O đĩa quá tải. Khác biệt riêng biệt là bạn phải xác định đúng cái nào đang nghẽn, và tiến trình nào gây ra nó. Bài này mình sẽ chỉ cho bạn bộ lệnh để chẩn đoán chính xác trên VPS Linux và cách xử lý từng trường hợp.

  • Tóm tắt nhanh: vmstat 1 cho bạn biết ngay CPU hay I/O nghẽn qua cột us, sywa.
  • iostat -x 1 giúp phát hiện đĩa quá tải qua chỉ số %utilawait.
  • pidstat 1 khoanh vùng chính xác tiến trình nào đang ngốn tài nguyên.
  • RAM nghẽn thường xuất hiện dưới dạng swap hoạt động liên tục, và free -h là lệnh kiểm tra đầu tiên.

Yêu cầu trước khi bắt đầu

Bài này áp dụng cho VPS chạy Linux (Ubuntu 24.04, Debian 12 hoặc AlmaLinux 9 đều được). Bạn cần quyền root hoặc user có quyền sudo để cài đặt công cụ và chạy lệnh chẩn đoán.

  • Một VPS Linux đang chạy, có thể truy cập SSH.
  • Quyền sudo để cài gói sysstat (chứa iostat, pidstat).
  • Hiểu cơ bản về terminal và đọc output dạng bảng.

Vì sao phải chẩn đoán trước khi nâng cấp

Phản xạ của nhiều người khi VPS chậm là lên web xem gói VPS Linux nào to hơn rồi nâng cấp ngay. Mình đã thấy không ít trường hợp nâng từ 2GB lên 8GB RAM mà website vẫn chậm, vì thủ phạm thực sự là một tiến trình PHP-FPM rò rỉ bộ nhớ hoặc một cron job chạy backup vào giờ cao điểm làm nghẽn I/O. Nâng cấp lúc đó chỉ tốn tiền mà không giải quyết gì.

Việc đầu tiên cần làm là xác định chính xác tài nguyên nào đang là nút thắt. Bộ ba công cụ vmstat, iostatpidstat (nằm trong gói sysstat) sẽ cho bạn bức tranh toàn cảnh về CPU, RAM, swap và I/O chỉ trong vài phút.

Bước 1 - Cài đặt bộ công cụ sysstat

Trên Ubuntu và Debian, cài sysstat bằng lệnh:

sudo apt update
sudo apt install sysstat -y

Trên AlmaLinux hoặc Rocky Linux, dùng dnf:

sudo dnf install sysstat -y

Sau khi cài xong, kiểm tra phiên bản để chắc chắn công cụ đã sẵn sàng:

iostat -V
pidstat -V

Output mong đợi là thông tin phiên bản sysstat, ví dụ sysstat version 12.7.2. Nếu không thấy, kiểm tra lại bước cài đặt. Gói này cung cấp đồng thời iostat, pidstatmpstat, nên chỉ cần cài một lần là đủ.

Bước 2 - Dùng vmstat để xác định CPU hay I/O nghẽn

vmstat là công cụ nhanh nhất để trả lời câu hỏi đầu tiên: CPU hay I/O đang nghẽn? Lệnh sau chạy và in ra một mẫu mỗi giây, tổng cộng 5 lần:

vmstat 1 5

Output trông tương tự thế này:

procs -----------memory---------- ---swap-- -----io---- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 2  0      0 412456  98776 3987234    0    0    12    34  567 1234  8  2 89  1

Bạn cần đọc các cột quan trọng sau:

  • r: số tiến trình đang chờ CPU. Nếu giá trị này lớn hơn số lõi CPU (kiểm tra bằng nproc), CPU đang quá tải.
  • wa: phần trăm thời gian CPU chờ I/O đĩa. Giá trị trên 10-20% liên tục là dấu hiệu rõ ràng của nghẽn I/O.
  • ussy: phần trăm CPU dùng cho user space và kernel. Tổng hai giá trị này cao gần rất cao trong khi wa thấp, nghĩa là CPU nghẽn.
  • siso: swap in và swap out. Cả hai khác 0 liên tục là dấu hiệu RAM không đủ.

Nếu wa cao, vấn đề nằm ở đĩa. Nếu us + sy gần rất cao và r lớn, vấn đề nằm ở CPU. Nếu swap liên tục hoạt động, vấn đề nằm ở RAM. Đây là bước định hướng quan trọng nhất trước khi đi sâu vào chi tiết.

Bước 3 - Kiểm tra RAM với free và swap

Khi nghi ngờ RAM, lệnh free -h cho bạn cái nhìn tổng quan ngay lập tức:

free -h

Output dạng:

               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       2.1Gi       245Mi        12Mi       1.5Gi       1.3Gi
Swap:          1.0Gi       876Mi       148Mi

Chú ý đến cột available, không phải free. available ước tính lượng RAM thực sự có thể dùng, bao gồm cả phần cache có thể thu hồi. Nếu available gần 0 và swap đã dùng nhiều, hệ thống đang thiếu RAM nghiêm trọng.

Để xem tiến trình nào ngốn RAM nhiều nhất, dùng:

ps aux --sort=-%mem | head -10

Lệnh này sắp xếp các tiến trình theo mức dùng RAM giảm dần và hiển thị 10 tiến trình hàng đầu. Nhìn vào cột %MEMRSS (bộ nhớ vật lý thực tế dùng, tính bằng KB). Tiến trình nào chiếm phần lớn RAM chính là nghi phạm hàng đầu.

Bước 4 - Phân tích I/O đĩa chi tiết với iostat

Khi vmstat cho thấy wa cao, hãy dùng iostat để xem đĩa nào đang quá tải và mức độ nghiêm trọng. Lệnh sau hiển thị số liệu mỗi giây, tổng 5 lần, ở chế độ mở rộng:

iostat -x 1 5

Output có bảng Device với nhiều cột. Ba cột quan trọng nhất:

  • %util: phần trăm thời gian đĩa bận xử lý yêu cầu. Giá trị trên 80-90% liên tục là đĩa đã quá tải.
  • await: thời gian trung bình (ms) để hoàn thành một yêu cầu I/O. Trên NVMe, giá trị này thường dưới 5ms; nếu lên tới vài chục ms, đĩa đang nghẽn.
  • r_awaitw_await: thời gian đọc và ghi riêng. Nếu w_await cao bất thường, có thể do ghi nhiều dữ liệu nhỏ hoặc thiếu RAM dẫn đến phải ghi swap.

Một lưu ý quan trọng: %util trên ổ SSD NVMe có thể gây hiểu nhầm. Vì NVMe xử lý song song rất tốt, %util cao đôi khi không phản ánh đúng mức nghẽn thực tế. Kết hợp với await để đánh giá chính xác hơn.

Bước 5 - Khoanh vùng tiến trình gây nghẽn với pidstat

Sau khi biết loại tài nguyên nghẽn, bước cuối là tìm ra tiến trình cụ thể. pidstat làm việc này tốt hơn hẳn top vì nó hiển thị số liệu theo từng tiến trình qua thời gian.

Xem tiến trình nào dùng CPU nhiều nhất, chạy mỗi giây trong 5 lần:

pidstat 1 5

Output dạng bảng với cột %CPU cho từng PID. Tiến trình nào duy trì %CPU cao trên 80-90% trong nhiều lần đo liên tiếp là thủ phạm.

Để xem chi tiết I/O của từng tiến trình, dùng thêm flag -d:

pidstat -d 1 5

Lệnh này hiển thị số KB đọc/ghi mỗi giây của từng tiến trình qua cột kB_rd/skB_wr/s. Nếu một tiến trình ghi hàng chục MB mỗi giây, bạn đã tìm ra nguyên nhân nghẽn I/O.

Trên VPS dùng VPS WordPress, thủ phạm I/O thường là MySQL/MariaDB hoặc cron job backup. Trên VPS chạy ứng dụng Node.js, có thể là tiến trình ghi log quá nhiều.

Bước 6 - Đọc kết quả và hướng xử lý từng loại nghẽn

Khi đã có đủ dữ liệu, việc xử lý khá rõ ràng theo từng trường hợp.

Nghẽn CPU

Dấu hiệu: cột r trong vmstat lớn hơn số lõi CPU, us + sy gần rất cao, wa thấp. pidstat cho thấy một hoặc vài tiến trình chiếm gần hết CPU.

Hướng xử lý: kiểm tra xem tiến trình đó có cần chạy không. Nếu là PHP-FPM hoặc worker Node.js, có thể cần giới hạn số worker trong cấu hình. Nếu là crontab chạy lệnh nặng vào giờ cao điểm, dời sang giờ thấp điểm. Trường hợp nhiều tiến trình hợp lệ cùng chạy, lúc đó mới nên cân nhắc nâng cấp gói VPS có nhiều vCPU hơn.

Thiếu RAM và swap

Dấu hiệu: cột available trong free -h rất thấp, siso trong vmstat liên tục khác 0. Hệ thống dùng swap nhiều khiến mọi thứ chậm rãi vì swap chậm hơn RAM rất nhiều.

Kiểm tra tiến trình nào ngốn RAM bằng ps aux --sort=-%mem | head -10. Nếu một ứng dụng rò rỉ bộ nhớ (RSS tăng dần theo thời gian), khởi động lại nó là giải pháp tạm thời. Về dài hạn, tối ưu cấu hình ứng dụng (ví dụ giảm pm.max_children trong PHP-FPM) hoặc nâng RAM là phương án. Bạn có thể tham khảo bài cấu hình swap và tối ưu bộ nhớ cho VPS RAM thấp để có thêm hướng xử lý chi tiết.

Nghẽn I/O

Dấu hiệu: wa trong vmstat duy trì trên 10-20%, await trong iostat -x cao bất thường.

Hướng xử lý: dùng pidstat -d tìm tiến trình ghi/đọc nhiều. Thường gặp nhất là database (MariaDB, PostgreSQL) hoặc cron job nén backup. Nếu là backup, hãy dời lịch chạy và giới hạn tốc độ bằng lệnh ionice. Nếu là database, tối ưu cấu hình buffer hoặc xem lại các truy vấn chậm. Nếu VPS của bạn dùng ổ cứng HDD, việc nâng cấp lên VPS NVMe sẽ cải thiện rõ rệt vì tốc độ đọc ghi nhanh gấp nhiều lần.

Các lỗi thường gặp khi chẩn đoán

Có vài sai lầm phổ biến khiến quá trình chẩn đoán đi sai hướng. Thứ nhất, chỉ nhìn top một lần rồi kết luận. Load của hệ thống thay đổi theo từng giây, bạn cần quan sát nhiều mẫu liên tiếp với vmstat 1 10 để có bức tranh ổn định.

Thứ hai, nhìn %MEM trong top mà không cộng cả phần cache. Linux dùng RAM trống cho cache rất tích cực, nên thấy free thấp là chuyện bình thường. Hãy luôn nhìn cột available trong free -h.

Thứ ba, bỏ qua việc kiểm tra giới hạn mềm. Nếu VPS của bạn nghẽn I/O, hãy chạy dmesg | tail -20 xem có thông báo nào về việc thiếu bộ nhớ (OOM killer) hoặc lỗi ổ đĩa không. Đôi khi vấn đề không phải do tài nguyên cạn mà do ổ đĩa sắp hỏng.

Câu hỏi thường gặp

Làm sao để biết CPU hay I/O đang nghẽn?

Chạy vmstat 1 5. Nếu cột wa duy trì trên 10-20%, I/O đang nghẽn. Nếu us + sy gần rất cao và wa thấp, CPU đang nghẽn. Cột r lớn hơn số lõi CPU cũng là dấu hiệu CPU quá tải.

Vì sao VPS dùng swap dù vẫn còn RAM trống?

Linux kernel có xu hướng dùng swap sớm để dành RAM cho cache. Tuy nhiên nếu swap bị dùng nhiều thật sự (vài trăm MB trở lên) trong khi available thấp, hệ thống đang thiếu RAM. Bạn có thể giảm mức độ dùng swap sớm bằng cách chỉnh tham số vm.swappiness về giá trị thấp hơn như 10 trong /etc/sysctl.conf.

iostat cho thấy %util rất cao nhưng VPS vẫn chạy tốt, có sao không?

Trên ổ NVMe, %util rất cao không hẳn là nghẽn vì NVMe xử lý song song nhiều lệnh cùng lúc. Hãy xem thêm cột await. Nếu await vẫn dưới 5-10ms, hệ thống I/O vẫn ổn. Nếu await tăng vọt lên hàng chục ms, lúc đó mới thực sự có vấn đề.

pidstat không có trong hệ thống thì phải làm sao?

Cài gói sysstat bằng lệnh sudo apt install sysstat -y trên Ubuntu/Debian, hoặc sudo dnf install sysstat -y trên AlmaLinux/Rocky. Nếu không muốn cài thêm, bạn có thể dùng top rồi nhấn phím x để highlight cột sắp xếp, nhưng pidstat vẫn tiện hơn nhiều.

Nghẽn I/O trên VPS dùng HDD có nên nâng cấp NVMe không?

Có. Nếu iostat -x cho thấy await cao và %util gần rất cao trong khi VPS dùng HDD, nâng cấp lên VPS NVMe sẽ cải thiện hiệu năng rõ rệt vì tốc độ đọc ghi ngẫu nhiên nhanh gấp nhiều lần. Đây là một trong những nâng cấp đáng giá nhất về hiệu năng I/O.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.