Sửa lỗi Redis: OOM command not allowed when used memory > 'maxmemory'

intermediate🔴 Redis2026-04-29| Linux (Ubuntu, Debian, CentOS), Docker, Redis 5.0 đến 7.2+

Error Message

OOM command not allowed when used memory > 'maxmemory'
#redis#devops#cơ sở dữ liệu#xử lý sự cố

LỗiRedis được thiết kế để hoạt động nhanh bằng cách lưu giữ mọi thứ trong RAM. Nhưng khi RAM đầy, mọi hoạt động sẽ dừng lại. Nếu bạn gặp lỗi này, nghĩa là ứng dụng của bạn đã cố gắng ghi dữ liệu vào một thực thể (instance) Redis vốn đã đạt đến 'ngưỡng giới hạn cứng'.

(error) OOM command not allowed when used memory > 'maxmemory'

Về cơ bản, Redis đã chạm đến giới hạn maxmemory được xác định trong tệp cấu hình, và các thiết lập hiện tại không cho phép nó xóa dữ liệu cũ để nhường chỗ cho dữ liệu mới. Như một biện pháp an toàn, nó chuyển sang chế độ chỉ đọc (read-only) đối với hầu hết các lệnh.

Chẩn đoán tức thìKhi log bắt đầu tràn ngập lỗi OOM, tôi kiểm tra chi tiết bộ nhớ ngay lập tức. Kết nối tới instance của bạn và chạy:

redis-cli info memory

Tập trung vào ba chỉ số sau:

  • used_memory_human: Kích thước dữ liệu thực tế (vd: 1.95G).- maxmemory_human: Giới hạn bạn đã cấu hình (vd: 2.00G).- maxmemory_policy: Đây thường là nguyên nhân chính.Nếu chính sách của bạn được đặt là noeviction, Redis sẽ không bao giờ tự động xóa các key. Nó sẽ đơn giản là từ chối mọi lệnh ghi mới cho đến khi bạn giải phóng không gian bộ nhớ thủ công hoặc tăng giới hạn.

Các bước khắc phục### 1. Giải pháp tạm thời: Tăng giới hạnNếu máy chủ của bạn còn dư RAM vật lý—ví dụ: một VPS 4GB chỉ mới sử dụng 2GB—bạn có thể khôi phục dịch vụ ngay lập tức bằng cách nâng giới hạn. Thay đổi này có hiệu lực ngay lập tức mà không cần khởi động lại:

# Tăng lên 3 Gigabytes
redis-cli config set maxmemory 3gb

Xác nhận giới hạn mới đã hoạt động:

redis-cli config get maxmemory

2. Tự động hóa dọn dẹp dữ liệu (Chính sách xóa)Tăng RAM chỉ là giải pháp tạm thời. Để thiết lập bền vững, bạn cần một chính sách xóa (eviction policy) để loại bỏ dữ liệu cũ khi bộ nhớ đầy. Đối với hầu hết các trường hợp sử dụng cache, allkeys-lru là lựa chọn tiêu chuẩn vì nó sẽ xóa các key ít được sử dụng nhất trước tiên.

redis-cli config set maxmemory-policy allkeys-lru

Dưới đây là ý nghĩa thực sự của các chính sách phổ biến:

  • allkeys-lru: Loại bỏ các key cũ nhất, ít được sử dụng nhất để nhường chỗ. Tốt nhất cho hầu hết các loại cache.- volatile-lru: Chỉ xóa các key có thiết lập thời gian hết hạn (TTL). Nguy hiểm nếu bạn quên đặt TTL.- allkeys-random: Chọn ngẫu nhiên các key để xóa. Chỉ sử dụng nếu tuổi thọ dữ liệu không quan trọng.### 3. Thiết lập thay đổi vĩnh viễnĐừng quên rằng các thay đổi qua redis-cli sẽ biến mất nếu máy chủ khởi động lại. Bạn phải cập nhật tệp cấu hình, thường nằm tại /etc/redis/redis.conf.
sudo nano /etc/redis/redis.conf

# Tìm các dòng này và cập nhật chúng:
maxmemory 3gb
maxmemory-policy allkeys-lru

Lưu tệp lại. Vì bạn đã áp dụng các thay đổi qua CLI, bạn không cần phải khởi động lại dịch vụ ngay lúc này.

4. Tìm kiếm các key chiếm nhiều bộ nhớĐôi khi vấn đề không phải do giới hạn thấp, mà do một key khổng lồ. Công cụ --bigkeys sẽ quét cơ sở dữ liệu để tìm các string, list hoặc set lớn nhất. Nó sử dụng lệnh SCAN nên không gây treo máy chủ, nhưng hãy chạy nó trong giai đoạn ít lưu lượng truy cập để đảm bảo an toàn.

redis-cli --bigkeys

Nếu bạn thấy một 'Set' duy nhất có 5 triệu thành viên, bạn đã tìm thấy nguyên nhân rò rỉ bộ nhớ.

Xác minhKiểm tra xem lệnh ghi đã hoạt động lại chưa bằng cách đặt một key thử nghiệm:

redis-cli set health_check "ok"

Nếu bạn thấy OK, ứng dụng của bạn đã có thể ghi dữ liệu trở lại. Tôi thường theo dõi thêm xu hướng bộ nhớ trong 60 giây:

redis-cli --interval 1 --stat

Chiến lược phòng ngừa- Đặt TTL cho mọi thứ: Trừ khi dữ liệu là tối quan trọng, hãy đặt thời gian hết hạn cho nó. Điều này ngăn Redis trở thành "nghĩa địa" của những dữ liệu bị lãng quên.- Quy tắc 80%: Cấu hình hệ thống giám sát để cảnh báo khi used_memory đạt 80% của maxmemory. Điều này giúp bạn có khoảng trống để xử lý trước khi lỗi OOM xảy ra.- Kiểm tra phân mảnh: Nếu used_memory_rss cao hơn đáng kể so với used_memory, bộ nhớ của bạn đang bị phân mảnh. Trên Redis 4.0+, bạn có thể thử CONFIG SET activedefrag yes để dọn dẹp trong chế độ nền.

Related Error Notes