Làm chủ systemd-run: Giới hạn CPU và RAM ‘tức thì’ cho script Linux

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Chạy script nặng mà không làm ‘treo’ server: Giải pháp từ systemd-run

Bạn đã bao giờ rơi vào cảnh chạy một script backup hoặc nén folder nặng vài chục GB, rồi bỗng dưng server ‘đứng hình’? CPU nhảy lên 100%, RAM cạn kiệt, còn Nginx thì bắt đầu trả về lỗi 504. Trước đây, mình hay dùng nice, nhưng nó chỉ chỉnh độ ưu tiên chứ không thể ‘khóa trần’ tài nguyên thực tế.

Trên server Ubuntu 22.04 (4GB RAM) mình quản lý, systemd-run là cứu cánh thực sự cho các tác vụ đột xuất. Công cụ này cho phép mình ra lệnh: “Script này chỉ được dùng tối đa 500MB RAM và 20% CPU”. Nếu vượt ngưỡng, systemd sẽ tự can thiệp, giữ cho các dịch vụ cốt lõi luôn an toàn.

Quick Start: Giới hạn tài nguyên trong 30 giây

Giả sử bạn cần chạy một script Python xử lý dữ liệu nhưng sợ nó ‘nuốt’ sạch RAM. Hãy dùng cấu trúc lệnh sau để giới hạn nó ở mức 500MB RAM và 30% của một nhân CPU:

sudo systemd-run --scope -p MemoryMax=500M -p CPUQuota=30% python3 heavy_script.py

Bóc tách các tham số quan trọng:

  • --scope: Chạy trực tiếp ở terminal hiện tại. Nếu bạn tắt terminal, lệnh sẽ dừng theo.
  • -p MemoryMax=500M: Ngưỡng RAM tối đa. Vượt quá mức này, tiến trình sẽ bị ‘trảm’.
  • -p CPUQuota=30%: Đảm bảo tiến trình không chiếm quá 30% tổng thời gian CPU.

Điểm hay nhất là systemd sẽ tạo ra một đơn vị tạm thời (transient unit) và áp dụng cgroups ngay lập tức. Bạn không cần hì hục tạo file .service thủ công như trước nữa.

Tại sao systemd-run ‘ăn đứt’ các công cụ cũ?

Nhiều tài liệu cũ vẫn hướng dẫn dùng ulimit. Tuy nhiên, ulimit rất khó quản lý theo nhóm tiến trình con. systemd-run thì khác, nó tận dụng cgroups (Control Groups). Đây chính là công nghệ lõi giúp Docker phân tách tài nguyên hiệu quả.

Phân biệt –scope và –unit

Tùy vào nhu cầu mà bạn chọn chế độ chạy phù hợp:

  • –scope: Chạy cùng shell hiện tại. Bạn sẽ thấy output hiển thị ngay trên màn hình.
  • –unit: Biến lệnh thành một service chạy ngầm. Rất hợp cho các tác vụ tốn vài tiếng đồng hồ.
sudo systemd-run --unit=backup-job -p MemoryMax=1G /usr/local/bin/backup.sh

Với --unit, bạn có thể thong thả tắt máy đi ngủ. Sáng mai chỉ cần check lại bằng lệnh systemctl status backup-job là xong.

Các thông số giới hạn ‘đắt giá’ nhất

Dưới đây là những flag mình thường xuyên áp dụng trong các dự án thực tế:

1. Giới hạn bộ nhớ (RAM)

  • MemoryMax: Ngưỡng cứng. Nếu vượt quá, OOM Killer sẽ can thiệp ngay lập tức.
  • MemoryHigh: Ngưỡng mềm. Khi chạm mức này, hệ thống sẽ ép tiến trình giải phóng bộ nhớ hoặc làm chậm nó lại thay vì giết chết ngay.
sudo systemd-run --scope -p MemoryHigh=800M -p MemoryMax=1G ./my-app

2. Giới hạn CPU

  • CPUQuota: Tính theo phần trăm. Nếu server có 4 nhân và bạn đặt 200%, script sẽ được dùng tối đa sức mạnh của 2 nhân.

3. Giới hạn đọc ghi đĩa (I/O)

Để tránh script backup làm nghẽn băng thông ổ cứng, hãy giới hạn tốc độ ghi:

sudo systemd-run --scope -p "IOWriteBandwidthMax=/dev/sda 10M" ./heavy-write-script.sh

Giám sát tài nguyên theo thời gian thực

Làm sao biết các lệnh đang chạy chiếm bao nhiêu tài nguyên? Đừng dùng top, hãy dùng systemd-cgtop. Nó hiển thị tài nguyên theo cấu trúc cgroups cực kỳ trực quan.

systemd-cgtop

Bạn sẽ thấy các transient unit hiện lên kèm con số CPU/RAM cụ thể. Nếu muốn dừng một tác vụ chạy ngầm, bạn chỉ cần dùng lệnh stop quen thuộc: sudo systemctl stop backup-job.

Kinh nghiệm thực chiến: Khi nào nên dùng?

Qua quá trình vận hành, mình thấy 3 kịch bản sau là đáng dùng nhất:

  1. Crawl dữ liệu: Các script Python rất hay bị rò rỉ bộ nhớ (memory leak). Đặt MemoryMax giúp script tự dừng trước khi nó kéo sập cả server.
  2. Nén Log cũ: Dùng gzip file log nặng thường đẩy Load Average lên rất cao. Giới hạn CPUQuota=15% giúp việc nén chạy lầm lì dưới nền mà không gây lag web.
  3. Thao tác qua SSH: Khi mạng chập chờn, dùng systemd-run --unit giúp lệnh luôn chạy an toàn kể cả khi mất kết nối.

Lưu ý: Bạn cần quyền sudo để can thiệp vào cgroups. Nếu muốn chạy quyền user thường, bạn phải cấu hình cgroup v2 delegation khá phức tạp, nên dùng sudo cho nhanh.

Lời kết

systemd-run không chỉ là một câu lệnh, nó là tư duy quản trị hệ thống hiện đại. Thay vì để script ‘chạy rông’, việc nhốt chúng vào một khung tài nguyên cố định giúp server của bạn luôn ổn định. Hãy thử áp dụng ngay vào các script chạy hàng ngày của bạn để thấy sự khác biệt.

Share: