Optimization

Vì sao VPS bị đầy RAM và cách xử lý hiệu quả

SSH vào VPS, gõ free -h thấy RAM gần cạn trong khi mình chỉ chạy Nginx và một trang WordPress. Đây là tình huống quen thuộc với bất kỳ ai thuê VPS Linux cấu hình thấp. Tin tốt là "đầy RAM" trên Linux gần như luôn có nguyên nhân rõ ràng, và bạn có thể xử lý được bằng vài lệnh sau.

Bài này hướng dẫn bạn chẩn đoán chính xác thứ đang ngốn RAM, phân biệt RAM thật và RAM ảo (cache), rồi áp dụng các biện pháp tối ưu từ nhẹ đến sâu. Môi trường áp dụng: Ubuntu 24.04 hoặc Debian 12, có quyền sudo hoặc root. Các lệnh đều kiểm chứng trên hai bản này.

  • Xác định ngay tiến trình ngốn RAM bằng top/htop thay vì đoán mò.
  • Hiểu buffer/cache không phải RAM "chết", Linux dùng nó để tăng tốc đọc đĩa và sẽ nhường lại khi cần.
  • Tối ưu MySQL/MariaDB và PHP-FPM là hai thủ phạm lớn nhất trên VPS chạy web.
  • Bật swap đúng cách và cấu hình vm.swappiness để tránh bị OOM Killer tắt tiến trình.

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

  • Một VPS chạy Ubuntu 24.04 hoặc Debian 12, quyền sudo hoặc root.
  • Truy cập SSH vào máy chủ.
  • Kiến thức cơ bản về dòng lệnh Linux (cd, nano, systemctl).

Vì sao bạn nên quan tâm đến RAM ngay lúc này

RAM là tài nguyên nhanh nhất nhưng đắt nhất trên VPS. Khi hết RAM, kernel buộc phải dùng swap (chậm hơn hàng chục lần) hoặc tệ hơn, bật OOM Killer để tắt tiến trình ngốn nhiều bộ nhớ nhất. Hậu quả thấy rõ: website chậm, SSH bị treo, hoặc dịch vụ chết bất thường. Việc hiểu rõ cơ chế này giúp bạn chủ động hơn là đi "dọn RAM" hàng ngày một cách vô nghĩa.

Bước 1 - Kiểm tra lượng RAM thực tế đang dùng

Lệnh đầu tiên cần chạy là free -h. Nó cho bạn góc nhìn tổng quan về RAM và swap.

free -h

Output điển hình trông như sau:

               total        used        free      shared  buff/cache   available
Mem:           1.9Gi       900Mi       120Mi        12Mi       920Mi       830Mi
Swap:          512Mi        10Mi       502Mi

Chú ý cột available, đây mới là con số bạn cần quan tâm. Nó cho biết RAM thực sự có thể dùng mà không cần swap. Nếu available còn vài trăm MB, VPS vẫn hoạt động bình thường, phần lớn RAM đang bị buffer/cache chiếm chứ không phải ứng dụng. Nhìn vào cột used và thấy 900Mi nhưng 920Mi là cache, rõ ràng ứng dụng của bạn chỉ dùng ~900Mi, phần còn lại là bộ nhớ đệm.

Buffer/cache là cách Linux tận dụng RAM rảnh để lưu dữ liệu đọc từ đĩa, giúp lần đọc sau nhanh hơn. Khi ứng dụng cần RAM, kernel tự động thu hồi phần này, vì vậy đừng coi nó là "đầy". Để kiểm tra nhanh tiến trình nào đang ngốn RAM, dùng top hoặc htop (cài bằng apt install htop). Nhấn Shift+M trong top để sắp xếp theo bộ nhớ.

top -o %MEM

Output sẽ liệt kê các tiến trình kèm %MEM. Nếu thấy mysqld hoặc php-fpm nằm top với vài trăm MB, đó chính là thủ phạm chính, bạn cần tối ưu chúng ở các bước sau.

Bước 2 - Tối ưu MySQL/MariaDB ngốn RAM

MySQL/MariaDB là "con nghiện" RAM kinh điển trên VPS nhỏ. Mặc định, cấu hình của nó sinh ra cho máy chủ có nhiều GB RAM, vì vậy chạy trên VPS 2GB sẽ nhanh chóng đầy. Kiểm tra xem bạn có đang chạy nó không:

systemctl status mysql || systemctl status mariadb

Nếu có, bạn cần xem lại các tham số trong file cấu hình /etc/mysql/mysql.conf.d/mysqld.cnf hoặc /etc/mysql/mariadb.conf.d/50-server.cnf (tuỳ bản). Ba tham số quan trọng nhất:

Tham số VPS 2GB VPS 4GB Giải thích
innodb_buffer_pool_size 512M 1G Vùng đệm dữ liệu InnoDB, lớn nhất trong MySQL
max_connections 50 100 Giới hạn kết nối đồng thời
performance_schema OFF ON Thu thập thông tin hiệu năng, tốn RAM

Mở file cấu hình bằng nano và điều chỉnh:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Tìm và thêm/sửa các dòng dưới đây trong section [mysqld]:

[mysqld]
innodb_buffer_pool_size = 512M
max_connections = 50
performance_schema = OFF

Lưu file, khởi động lại MySQL và kiểm tra RAM đã giảm chưa:

sudo systemctl restart mysql
free -h

Bạn sẽ thấy used giảm đi vài trăm MB ngay lập tức. Đối với VPS RAM thấp, mẹo hay là dùng mysqltuner để tự gợi ý tham số, chạy vài phút rồi đọc output:

sudo apt install mysqltuner -y
sudo mysqltuner

Script này phân tích trạng thái MySQL và đưa ra khuyến nghị cụ thể, rất hợp cho ai không muốn tự mày mò từng tham số.

Bước 3 - Giới hạn bộ nhớ PHP-FPM

Mỗi tiến trình php-fpm xử lý một request PHP và chiếm khoảng 30-80MB RAM. Nếu cấu hình cho phép 30 tiến trình, bạn có thể mất tới 2GB RAM chỉ cho PHP. Cấu hình nằm tại /etc/php/8.3/fpm/pool.d/www.conf (phiên bản PHP có thể khác).

Ba tham số cần chú ý: pm, pm.max_children, pm.start_servers. Cách tính đơn giản: lấy RAM dành cho PHP chia cho dung lượng mỗi tiến trình. Ví dụ VPS 2GB RAM, dành 1GB cho PHP, mỗi tiến trình ~50MB, vậy max_children = 20.

sudo nano /etc/php/8.3/fpm/pool.d/www.conf

Sửa các giá trị:

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500

Giải thích nhanh: pm.max_requests giúp PHP-FPM tự động giải phóng bộ nhớ của các tiến trình bị rò rỉ sau 500 request, tránh RAM tăng dần theo thời gian. Khởi động lại PHP-FPM:

sudo systemctl restart php8.3-fpm
free -h

Nếu bạn chạy WordPress, nên xem xét dùng VPS WordPress có sẵn LiteSpeed hoặc cài plugin cache để giảm số request PHP phải xử lý. RAM giảm thấy rõ.

Bước 4 - Bật Swap và cấu hình swappiness

Swap là phân vùng hoặc file trên ổ đĩa dùng làm RAM dự phòng. Khi RAM đầy, kernel chuyển các trang bộ nhớ ít dùng sang swap, nhường chỗ cho ứng dụng. Nó chậm hơn RAM nhưng giúp hệ thống không bị OOM Killer tắt tiến trình.

Kiểm tra swap đã bật chưa:

swapon --show

Nếu trống, tạo file swap 2GB (bằng dung lượng RAM):

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Để swap tồn tại sau khi reboot, thêm vào file /etc/fstab bằng echo:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Tham số vm.swappiness quyết định mức độ ưu tiên dùng swap (0-100). Giá trị mặc định 60 thường quá cao cho VPS, kernel sẽ dùng swap ngay cả khi RAM còn rảnh. Đặt về 10 để chỉ dùng swap khi RAM thực sự cạn:

sudo sysctl vm.swappiness=10

Để áp dụng lâu dài, thêm vào /etc/sysctl.conf:

echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

Bạn cũng có thể giảm áp lực lên RAM bằng cách chuyển một số dịch vụ nặng sang VPS n8n hoặc container Docker riêng, giúp cô lập tài nguyên tốt hơn.

Xử lý lỗi thường gặp

Lỗi 1: "Cannot allocate memory" khi chạy lệnh. Đây là dấu hiệu RAM và swap đã cạn hoàn toàn. Kiểm tra ngay bằng free -h, nếu available = 0, hãy kill tiến trình ngốn nhất bằng:

sudo kill -9 $(ps aux --sort=-%mem | head -2 | tail -1 | awk '{print $2}')

Lỗi 2: MySQL không khởi động lại được sau khi sửa config. Kiểm tra log lỗi tại /var/log/mysql/error.log. Lỗi hay gặp là sai cú pháp hoặc đặt innodb_buffer_pool_size quá lớn so với RAM. Khôi phục giá trị cũ hoặc giảm xuống rồi thử lại.

Lỗi 3: Swapfile "permission denied" khi tạo. Kiểm tra bạn dùng sudo và ổ đĩa không phải định dạng exFAT/FAT32 (không hỗ trợ fallocate và swapon). Nếu dùng file-based swap trên ổ đĩa có dung lượng thấp, hãy kiểm tra df -h trước.

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

Vì sao VPS của tôi đầy RAM dù không cài gì nặng?

Linux luôn cố dùng RAM tối đa cho buffer/cache để tăng tốc độ, vì vậy free -h thường hiển thị "used" cao. Hãy nhìn cột available. Nếu available vẫn còn nhiều, hệ thống chưa thực sự đầy RAM, chỉ là RAM đang được tận dụng. Thủ phạm thật sự thường là MySQL/MariaDB và PHP-FPM với cấu hình mặc định sinh ra cho máy chủ lớn.

Nên bật swap dung lượng bao nhiêu cho VPS?

Kinh nghiệm phổ biến là bằng dung lượng RAM cho VPS dưới 4GB, và bằng 50% RAM cho VPS lớn hơn. Ví dụ VPS 2GB nên tạo swap 2GB. Swap không thay thế RAM nhưng là phao cứu sinh tránh OOM Killer tắt tiến trình khi có đột biến.

Xóa bộ nhớ cache có giúp giải phóng RAM không?

Lệnh sync; echo 3 > /proc/sys/vm/drop_caches xóa cache và khiến RAM trông rảnh hơn, nhưng không nên lạm dụng. Cache giúp đọc đĩa nhanh hơn, kernel sẽ tự thu hồi khi cần. Thay vì xóa cache, hãy tìm và tối ưu nguyên nhân gốc đang ngốn RAM thật là ứng dụng.

Làm sao để biết tiến trình nào đang ngốn RAM?

Dùng top -o %MEM hoặc htop để xem danh sách tiến trình theo thứ tự RAM sử dụng. Bạn sẽ thấy ngay mysqld, php-fpm hay java nào đang chiếm nhiều nhất và xử lý đúng đối tượng.

Bấm "nâng cấp RAM" có phải cách riêng biệt không?

Không. Với VPS 2GB, tối ưu MySQL và PHP-FPM có thể giảm 30-50% RAM sử dụng, đủ cho website trung bình. Tối ưu xong mà vẫn thiếu mới nên cân nhắc nâng cấp bảng giá VPS lên gói 4GB, xem thêm gói VPS Linux NVMe phù hợp nhu cầu.

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ế.