Optimization

Giảm chi phí VPS mà không mất hiệu năng: 7 việc làm được ngay

Bạn có một VPS đang chạy ổn, nhưng cảm giác máy ì hơn trước? Hay bạn đang thuê gói 4GB RAM mà htop lúc nào cũng báo đỏ? Tin vui là có thể tối ưu chi phí VPS mà không cần nâng cấp, thậm chí còn chạy mượt hơn. Mình từng gặp một con VPS 2GB RAM, chạy WordPress + WooCommerce, lúc nào cũng swap đầy. Sau 7 bước dưới đây, RAM free tăng gấp đôi, thời gian response giảm 40%. Tất cả đều làm được ngay trên VPS đang chạy.

Tóm tắt nhanh

  • Gỡ các service không dùng đến (MySQL thứ hai, Apache dư thừa), tiết kiệm ngay 200-400MB RAM.
  • Chỉnh pm.max_children của PHP-FPM dựa trên RAM thật, tránh OOM kill.
  • Đặt MariaDB InnoDB buffer pool ở 50-60% RAM khả dụng, không lãng phí, không thiếu.
  • Bật opcache, nén Brotli, logrotate, giảm CPU và I/O mà không mất gì.

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

  • Một VPS chạy Ubuntu 24.04 hoặc Debian 12 với quyền sudo hoặc root.
  • Đã cài sẵn PHP-FPM, MariaDB, Nginx, hoặc stack tương tự.
  • Có kiến thức cơ bản về systemctl, htop, free.

Vì sao phải tối ưu ngay từ đầu?

Hầu hết VPS khi cài mặc định từ control panel hoặc distro đều chạy với cấu hình "an toàn", tức là dùng nhiều RAM hơn cần. Bạn mất tiền cho phần RAM không dùng đến, và khi server dùng swap quá nhiều thì hiệu năng giảm mạnh. Một VPS 2GB RAM được tinh chỉnh tốt có thể chạy tốt hơn VPS 4GB RAM không tối ưu. Đó là lý do các thuê VPS Linux dù cấu hình thấp vẫn chạy ngon nếu biết cách.

Bước 1, Gỡ service thừa (low-hanging fruit)

Đầu tiên, xem cái gì đang ngốn RAM. Chạy systemd-cgtop hoặc htop và nhấn F6 để sort theo MEM%. Bạn sẽ thấy bất ngờ: có thể có MySQL thứ hai (một cái đang chạy + một cái tắt lịm từ lần cài panel), Apache mặc định dù dùng Nginx, hay Postfix nếu không gửi mail.

# Kiểm tra tất cả service đang active
systemctl list-units --type=service --state=running

# Nếu thấy apache2 đang chạy trong khi dùng Nginx
sudo systemctl stop apache2
sudo systemctl disable apache2

# Nếu có MySQL/MariaDB dư (ví dụ mysql và mariadb cùng tồn tại)
sudo systemctl stop mysql
sudo systemctl disable mysql

# Xoá gói không cần (chỉ apache2 cũng tiết kiệm 20-50MB)
sudo apt remove --purge apache2* -y
sudo apt autoremove -y

Verify: Chạy free -h trước và sau, bạn sẽ thấy RAM free tăng lên 100-300MB ngay lập tức. Với VPS 2GB, mình từng lấy lại được 400MB chỉ từ bước này.

Bước 2, Chỉnh PHP-FPM pm.max_children đúng với RAM

PHP-FPM là kẻ ngốn RAM nhất nếu để mặc định. Giá trị pm.max_children quá cao sẽ làm server tạo quá nhiều worker, dẫn đến OOM (Out Of Memory). Công thức: lấy RAM trống (sau khi trừ OS và MariaDB), chia cho RAM trung bình mỗi worker (~30-40MB cho PHP 8.3 opcache-on).

# Xem RAM mỗi worker hiện tại dùng
ps aux | grep php-fpm | grep -v grep | awk '{sum+=$6} END {print sum/NR/1024 " MB"}'

# Mở file cấu hình pool (thường là /etc/php/8.3/fpm/pool.d/www.conf)
sudo nano /etc/php/8.3/fpm/pool.d/www.conf

# Sửa các dòng:
pm = dynamic
pm.max_children = 8    # Ví dụ VPS 2GB RAM: 2GB - 512MB OS - 512MB DB = ~1GB / 40MB = ~25 worker. Nhưng an toàn để 8-12.
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6

# Restart
sudo systemctl restart php8.3-fpm

Verify: Đo lại free -h. Nếu trước đó có 20 worker chạy ngốn 800MB, giờ còn 4 worker = 160MB. Website vẫn chạy nhanh.

Bước 3, MariaDB InnoDB buffer pool vừa đủ

MariaDB mặc định thường để buffer pool rất nhỏ (128MB) hoặc rất lớn (nếu dùng auto-config). Với VPS nhỏ, nên đặt thủ công ở 50-60% RAM khả dụng (sau trừ OS). Nếu VPS 2GB, OS chiếm ~512MB, MariaDB có thể dùng 768MB-1GB.

# Mở file cấu hình
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

# Sửa hoặc thêm dòng này trong [mysqld]:
innodb_buffer_pool_size = 768M    # Cho VPS 2GB RAM
# Hoặc:
innodb_buffer_pool_size = 1G      # Cho VPS 4GB RAM

# Restart
sudo systemctl restart mariadb

Cảnh báo: Đừng đặt trên 70% RAM, gây swap ngược. Kiểm tra sau đó bằng htop để xem swap có tăng không.

Bước 4, Bật Opcache và nén Brotli (gần như free)

PHP Opcache compile code PHP thành bytecode và lưu vào shared memory. Bật lên là tiết kiệm 20-50% CPU cho PHP.

# Kiểm tra xem opcache đã bật chưa
php -i | grep opcache.enable
# Nếu ra "opcache.enable => Off" thì sửa file php.ini
sudo nano /etc/php/8.3/fpm/php.ini
# Tìm và bỏ comment:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
# Restart
sudo systemctl restart php8.3-fpm

Nén Brotli cho Nginx giảm dung lượng truyền tải xuống 20-30% so với Gzip, giảm bandwidth và tăng tốc load.

# Cài module Brotli cho Nginx
sudo apt install nginx-extras -y   # Ubuntu/Debian
# Hoặc build từ source nếu cần (hơi phức tạp hơn)

# Thêm vào http block của nginx.conf:
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript image/svg+xml;

# Kiểm tra cú pháp
sudo nginx -t
sudo systemctl reload nginx

Bước 5, Nén ảnh tự động bằng ImageMagick hoặc ShortPixel

Ảnh chiếm 60-80% dung lượng trang web. Nếu VPS bạn chạy WordPress, hãy dùng plugin nén ảnh tự động (ShortPixel, Imagify) hoặc script thủ công để nén ảnh cũ. Mỗi MB ảnh nén đi là giảm bandwidth và tăng tốc, gián tiếp giảm tải CPU và RAM cho PHP/DB.

# Cài ImageMagick
sudo apt install imagemagick -y

# Nén tất cả ảnh .jpg trong thư mục wp-content/uploads/ xuống 80% chất lượng
find /var/www/domains/example.com/wp-content/uploads/ -name "*.jpg" -exec convert {} -quality 80 {} \;

Lệnh này chạy vài phút, nhưng sau đó mỗi lần load ảnh sẽ nhẹ hơn rõ rệt.

Bước 6, Logrotate: dọn log cũ, đừng để log ngốn đầy ổ

Log là thứ âm thầm ngốn hết ổ cứng. Một VPS chạy 6 tháng không logrotate có thể có file log 2-3GB. Khi ổ đầy, ứng dụng ngừng hoạt động. Logrotate mặc định đã được cài, nhưng cần kiểm tra cấu hình.

# Xem cấu hình logrotate cho Nginx, MariaDB
sudo cat /etc/logrotate.d/nginx
sudo cat /etc/logrotate.d/mariadb

# Mẫu cấu hình hợp lý cho Nginx (thêm vào /etc/logrotate.d/nginx):
/var/log/nginx/*.log {
    daily
    rotate 14       # Giữ 14 ngày
    compress
    delaycompress
    missingok
    notifempty
    create 640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

Verify: du -sh /var/log/, bạn sẽ thấy dung lượng giảm rõ rệt sau lần chạy logrotate đầu tiên (sudo logrotate -f /etc/logrotate.conf).

Bước 7, Tắt cron rác và tối ưu lịch cron

Cron chạy mỗi phút (ví dụ: session cleanup WordPress, cache reset plugin) làm CPU luôn ở mức 5-10% dù không có traffic. Kiểm tra crontab của root và www-data.

# Xem cron đang chạy
sudo crontab -l
sudo crontab -u www-data -l

# Xem cron trong /etc/cron.d/
ls -la /etc/cron.d/
cat /etc/cron.d/*

# Nếu thấy cron WordPress "wp-cron.php" chạy mỗi phút, hãy tắt nó trong wp-config.php:
define('DISABLE_WP_CRON', true);
# Sau đó setup một real cron chạy mỗi 15 phút thay vì mỗi phút:
*/15 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Kết quả: CPU idle tăng từ 80% lên 95%, giảm load trung bình.

Đo hiệu năng trước và sau

Đừng đoán mò. Hãy đo bằng số liệu thật:

  • RAM: free -h, ghi số "used" và "available" trước và sau từng bước.
  • CPU load: uptime, load average 1,5,15.
  • Swap: swapon --show, nếu swap giảm là thành công.
  • Web performance: Dùng curl -o /dev/null -s -w '%{time_total}\n' https://example.com đo thời gian response.
  • DB query: mysqladmin status, xem số query mỗi giây.

Sau 7 bước, bạn thường thấy RAM giảm 30-50%, CPU load giảm 20-40%, thời gian response nhanh hơn 10-30%, tất cả đều miễn phí. Đây là cách tối ưu chi phí VPS hàng đầu mà không phải nâng cấp gói.

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

  • Sau khi giảm pm.max_children, website chậm hơn: Tăng từ từ (2 worker một lần) cho đến khi load trung bình ổn. Dùng htop để theo dõi.
  • MariaDB restart không được: Kiểm tra log journalctl -u mariadb -n 50. Thường do buffer pool lớn hơn RAM khả dụng.
  • Sau logrotate, Nginx không phục vụ log mới: Thiếu dòng kill -USR1 trong postrotate. Sửa lại cấu hình.

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

Tôi có thể tối ưu VPS 1GB RAM không?

Có. Các bước trên vẫn áp dụng, nhưng cẩn thận buffer pool của MariaDB chỉ nên đặt 256-384MB, và pm.max_children chỉ 4-6.

Có cần nâng cấp gói VPS khi website phát triển không?

Chỉ khi bạn đã tối ưu hết mà CPU vẫn rất cao hoặc RAM vẫn đầy. Khi đó, nâng lên gói cao hơn (ví dụ từ VNx2 lên VNx4) có hiệu quả rõ rệt. Bạn có thể tham khảo bảng giá VPS để chọn gói phù hợp.

Làm sao biết VPS mình đang thiếu RAM hay CPU?

Dùng htop, nếu RAM đầy và swap nhiều thì thiếu RAM. Nếu load average cao gấp 2-3 lần số core CPU thì thiếu CPU.

Có nên tắt hẳn MariaDB nếu dùng SQLite không?

Tuỳ ứng dụng. MariaDB vẫn nhẹ hơn so với lợi ích nếu bạn có nhiều truy vấn. VPS 2GB có thể chạy MariaDB + PHP + Nginx rất ngon nếu cấu hình đúng.

Tôi nên thuê VPS nào để dễ tối ưu?

Nên chọn VPS full root (KVM), bạn mới có toàn quyền chỉnh kernel parameters, swap, buffer pool. VPS shared hosting không cho.

Tối ưu có ảnh hưởng đến bảo mật không?

Không. Các bước trên không liên quan đến firewall, SSH key, fail2ban. Bạn vẫn nên giữ các biện pháp bảo mật.

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