Tối ưu hóa Linux OOM Killer cho VPS: Hướng dẫn thực hành
12 phút đọc - 8 tháng 6, 2026

Điều chỉnh Linux OOM killer trên VPS của bạn để bảo vệ cơ sở dữ liệu và SSH, giới hạn các quá trình chạy quá mức bằng cgroups và ngăn chặn các dịch vụ không liên quan bị ngắt.
Tối ưu hóa Linux OOM killer cho VPS
Linux OOM killer là biện pháp cuối cùng của kernel khi bộ nhớ cạn kiệt: nó chọn một tiến trình và chấm dứt tiến trình đó để duy trì hệ thống hoạt động. Trên VPS, nơi RAM hạn chế và không có nơi nào để dự phòng, lựa chọn mặc định thường là sai lầm. Cơ sở dữ liệu của bạn bị ngắt, một tiến trình chạy lâu dài lại tồn tại, và bạn phải tự tìm hiểu lý do tại sao. Hướng dẫn này giải thích cách OOM killer đánh giá các tiến trình, cách ưu tiên đánh giá đó cho các dịch vụ quan trọng của bạn, và cách sử dụng cgroups để một tiến trình chạy tràn không thể kéo theo toàn bộ hệ thống sụp đổ.
Cách OOM killer chọn nạn nhân
Khi kernel không thể thu hồi đủ bộ nhớ thông qua việc xóa bộ đệm trang hoặc hoán đổi, nó sẽ gọi OOM killer. Mỗi tiến trình có một oom_score điểm từ 0 đến 1000, chủ yếu được tính từ Resident Set Size (RSS) và mức sử dụng swap. Quá trình có điểm số cao nhất sẽ nhận được SIGKILL.
RSS chiếm phần lớn trong phép tính, đó là lý do tại sao việc giết quá trình hầu như luôn nhắm vào quá trình tiêu thụ bộ nhớ nhiều nhất. Đó thường là cơ sở dữ liệu, máy chủ ứng dụng hoặc bất kỳ quá trình tồn tại lâu dài nào đang thực hiện công việc hữu ích nhất. Quá trình thực sự kích hoạt việc phân bổ, tức là "invoker", hiếm khi là quá trình bị chấm dứt.
Có hai loại sự kiện OOM mà bạn cần phân biệt:
- OOM toàn cục: máy chủ (hoặc toàn bộ VPS của bạn) đã hết RAM và bộ nhớ ảo. Hệ điều hành quét mọi tiến trình và kết thúc tiến trình có điểm số cao nhất.
- Cgroup OOM: một cgroup cụ thể đã đạt đến giới hạn bộ nhớ của nó. Kernel chỉ giết các tiến trình bên trong cgroup đó, ngay cả khi phần còn lại của hệ thống vẫn còn bộ nhớ trống.
Nếu bạn đã định cấu hình giới hạn đơn vị systemd hoặc đang chạy các container, hầu hết các sự kiện OOM của bạn sẽ là cgroup OOM. Đó là một điều tốt: phạm vi ảnh hưởng được hạn chế.
Phát hiện áp lực bộ nhớ trước khi hệ thống ngừng hoạt động
Các sự kiện OOM hầu như không bao giờ xảy ra đột ngột. Thường có một khoảng thời gian áp lực tăng dần trước đó, và mục tiêu của việc giám sát là phát hiện ra nó trong khoảng thời gian đó.
free -h cung cấp cho bạn cái nhìn tổng quan về hệ thống. Cột quan trọng là available, không phải free: nó tính đến bộ đệm trang có thể thu hồi và phản ánh dung lượng bạn thực sự có thể phân bổ mà không cần hoán đổi. Giữ MemAvailable ở mức khoảng 10 đến 15 phần trăm MemTotal ở mức tải cao nhất.
Để phân bổ theo từng tiến trình, hãy sắp xếp theo RSS:
ps aux --sort=-%mem | head -10Hoặc sử dụng htop và sắp xếp theo RES. Các giá trị bạn thấy ở đây được đưa trực tiếp vào hệ thống chấm điểm của kernel, do đó các mục hàng đầu là các mục tiêu OOM có khả năng cao nhất.
Trên các kernel 4.20 trở lên, Thông tin Ứng suất (Pressure Stall Information) là hệ thống cảnh báo sớm đáng được tích hợp vào hệ thống giám sát:
cat /proc/pressure/memoryCon some avg10 số liệu này là tỷ lệ phần trăm thời gian mà ít nhất một tác vụ bị đình trệ do chờ bộ nhớ trong mười giây qua. Dưới 5 phần trăm là ổn. Các giá trị duy trì trên 10 phần trăm có nghĩa là hệ thống đang tiêu tốn thời gian thực bị chặn lại do thu hồi bộ nhớ, và việc hệ thống bị OOM là hoàn toàn có thể xảy ra.
Tình trạng swap thrashing xuất hiện trong vmstat 1 dưới dạng si và so kéo dài theo thời gian. Một lượng nhỏ swap thường trú là vô hại. Việc liên tục đưa vào và lấy ra khỏi swap thì không.
Bảo vệ các quy trình quan trọng bằng oom_score_adj
Điểm số mà kernel tính toán có thể được điều chỉnh theo từng quy trình thông qua oom_score_adj, trên thang điểm từ -1000 (miễn nhiễm) đến +1000 (giết tôi trước). Sự điều chỉnh được thêm trực tiếp vào điểm số cuối cùng.
Để thực hiện thay đổi một lần đối với một quy trình đang chạy:
echo -500 | sudo tee /proc/$(pidof sshd)/oom_score_adjĐối với bất kỳ điều gì bạn muốn duy trì sau khi khởi động lại, hãy thiết lập nó trong đơn vị systemd. Đó là vị trí thích hợp cho sshd, cơ sở dữ liệu của bạn và bất kỳ thứ gì khác mà bạn không thể để mất:
[Service]
OOMScoreAdjust=-900Các giá trị mặc định hợp lý để bắt đầu:
- sshd: -1000. Nếu bạn mất quyền truy cập từ xa trong một cuộc khủng hoảng bộ nhớ, việc khôi phục sẽ trở nên khó khăn hơn rất nhiều.
- MySQL, PostgreSQL, Redis: -800 đến -900. Bảo vệ mạnh mẽ mà không khiến chúng hoàn toàn không thể can thiệp trong tình huống thảm họa thực sự.
- Các công cụ ứng dụng, công việc hàng loạt, tác vụ cron: +100 đến +500. Đây là những quy trình mà bạn thà thấy chúng bị ngắt hơn là cơ sở dữ liệu của mình.
Đừng đặt tất cả thành -1000. Nếu không có gì có thể bị ngắt, kernel cuối cùng sẽ hoảng loạn hoặc bị đóng băng, điều này còn tồi tệ hơn.
Giới hạn bộ nhớ bằng cgroups và systemd
Việc điều chỉnh điểm số ảnh hưởng đến việc ai sẽ bị loại bỏ. Cgroups ảnh hưởng đến việc liệu việc loại bỏ toàn bộ có xảy ra hay không. Bằng cách đặt giới hạn trên cứng cho mỗi dịch vụ, bạn đẩy các lỗi bộ nhớ vào một cgroup duy nhất thay vì để một quá trình làm cạn kiệt toàn bộ VPS.
Trong tệp đơn vị systemd:
[Service]
MemoryHigh=400M
MemoryMax=512M
OOMPolicy=stop
Restart=on-failure
RestartSec=5sMemoryHigh là một cơ chế giới hạn mềm: nhân hệ thống sẽ thu hồi các trang bộ nhớ từ cgroup một cách quyết liệt khi vượt quá điểm này nhưng không giết bất kỳ tiến trình nào. MemoryMax là giới hạn cứng. Nếu cgroup cố gắng phân bổ vượt quá giới hạn này, kernel sẽ ngắt một tiến trình bên trong cgroup. Với Restart=on-failure dịch vụ sẽ khởi động lại ngay lập tức.
Trên cgroup v2 (Ubuntu 22.04 trở lên, Debian mới nhất, RHEL 9), memory.oom.group hệ điều hành sẽ kết thúc tất cả các tiến trình trong cgroup cùng lúc thay vì để lại các tiến trình mồ côi. Điều này hữu ích cho các dịch vụ đa tiến trình như các nhóm PHP-FPM, nơi một nhóm bị kết thúc một nửa có thể hoạt động không ổn định.
Một số lưu ý cụ thể cho ứng dụng đáng áp dụng:
- PHP-FPM: thiết lập
pm = ondemandtrên các máy chủ VPS nhỏ và thiết lậppm.max_childrendựa trên RSS trung bình trên mỗi worker, không phải giá trị mặc định. Một pool được định cỡ với 4 GB dung lượng trống trên một VPS 2 GB sẽ gặp lỗi OOM ngay lần đầu tiên khi đầy. - Node.js: giới hạn heap V8 bằng
--max-old-space-size=512(tính bằng MB). Nếu không có giới hạn này, Node sẽ tiếp tục mở rộng cho đến khi kernel can thiệp. - MySQL và PostgreSQL:
innodb_buffer_pool_sizevàshared_buffersnên để lại dung lượng trống rõ ràng cho bộ đệm trang của hệ điều hành, bộ nhớ kết nối và bất kỳ người thuê nào khác trên máy chủ. Các giá trị mặc định giả định đây là một máy chủ chuyên dụng.
Đọc nhật ký sau sự kiện OOM
Khi OOM killer kích hoạt, kernel sẽ ghi một báo cáo chi tiết vào bộ đệm vòng (ring buffer). Trích xuất nó bằng cách:
dmesg -T | grep -iE 'killed process|out of memory'
journalctl -k --grep='Out of memory'Khối cần đọc kỹ bắt đầu từ người gọi và kết thúc với nạn nhân. Hạt nhân in ra danh sách tác vụ đầy đủ với RSS của mỗi quá trình, mức sử dụng swap và oom_score_adj. Có ba điều đáng kiểm tra:
- Giới hạn.
CONSTRAINT_NONEcó nghĩa là OOM toàn cục,CONSTRAINT_MEMCGcó nghĩa là một cgroup đã đạt đến giới hạn của nó. Cách khắc phục khác nhau tùy theo từng trường hợp. Free swap. Nếu đây là0kB, cả RAM và vùng swap đều đã cạn kiệt. Hoặc là thêm vùng swap, tăngMemoryMaxtrên quá trình gây ra lỗi, hoặc giảm độ đồng thời.- Điểm số của quá trình bị ảnh hưởng so với tất cả các quá trình khác. Nếu điểm số của quá trình bị ảnh hưởng không cao hơn nhiều so với một vài quá trình tiếp theo, thì
oom_score_adjkhông đủ hiệu quả. Hãy nới rộng khoảng cách.
Đối với các trường hợp OOM của cgroup cụ thể, bộ đếm kill nằm memory.events bên trong cgroup:
cat /sys/fs/cgroup/system.slice/mysql.service/memory.eventsSố lần oom_kill có nghĩa là dịch vụ đó liên tục chạm ngưỡng giới hạn. Đó là tín hiệu để tăng MemoryMax, phân tích tải công việc hoặc chuyển dịch vụ sang gói tài nguyên lớn hơn, chứ không phải cứ khởi động lại nó liên tục.
Kết luận
Điều chỉnh OOM killer không phải là để loại bỏ nó. Mà là để kiểm soát quá trình nào sẽ phải trả giá khi bộ nhớ cạn kiệt, và thu hẹp phạm vi ảnh hưởng khi điều đó xảy ra. Mô hình được áp dụng trong sản xuất:
- Bảo vệ các dịch vụ mà bạn không thể để mất, đặc biệt là sshd và cơ sở dữ liệu của bạn.
- Giới hạn mọi thứ khác bằng
MemoryMaxtrong một đơn vị systemd để một quá trình chạy tràn chỉ gây ra một lần khởi động lại, chứ không phải sự cố ngừng hoạt động. - Theo dõi PSI và
MemAvailablethay vì chờ đợidmesgđể biết tình hình sau đó. - Dành 15 đến 20 phần trăm RAM làm dung lượng dự phòng. Việc tối ưu hóa không thể bù đắp cho một VPS quá nhỏ so với khối lượng công việc.
Nếu áp lực bộ nhớ của bạn là do cấu trúc chứ không phải do cấu hình, bạn cần thêm RAM hoặc bộ nhớ đệm nhanh hơn. Các gói VPS của FDC Servers chạy trên AMD EPYC với bộ nhớ NVMe, giúp duy trì tốc độ đọc từ bộ nhớ đệm đủ nhanh để các đợt tăng đột biến ngắn về bộ nhớ không leo thang thành việc hệ thống bị ngắt.

Tối ưu hóa Linux OOM Killer cho VPS: Hướng dẫn thực hành
Điều chỉnh Linux OOM killer trên VPS của bạn để bảo vệ cơ sở dữ liệu và SSH, giới hạn các quá trình chạy quá mức bằng cgroups và ngăn chặn các dịch vụ không liên quan bị ngắt.
12 phút đọc - 8 tháng 6, 2026
Kiểm soát lưu lượng Linux (tc): Hướng dẫn thực hành
12 phút đọc - 5 tháng 6, 2026

Bạn có thắc mắc hoặc cần giải pháp tùy chỉnh?
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức