Chuyện gì vừa xảy ra?
Ứng dụng của bạn gặp lỗi này khi ghi vào Redis:
MISCONF Redis is configured to save RDB snapshots, but it's currently not able to persist to disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
Redis đang chặn toàn bộ lệnh ghi (SET, HSET, LPUSH, v.v.) vì một lần lưu nền (BGSAVE) trước đó đã thất bại. Theo mặc định, Redis dừng nhận lệnh ghi khi không thể lưu dữ liệu. Đây là cơ chế an toàn có chủ đích — thà dừng hẳn còn hơn mất dữ liệu mà không có cảnh báo.
Ba nguyên nhân phổ biến nhất: đĩa đầy, tiến trình Redis thiếu quyền ghi vào thư mục dữ liệu, hoặc thư mục RDB không còn tồn tại.
Bước 1: Kiểm tra log Redis trước
Bắt đầu từ đây — log hầu như luôn cho biết chính xác điều gì đã thất bại:
# Kiểm tra file log của Redis
tail -n 50 /var/log/redis/redis-server.log
# Hoặc nếu chạy qua systemd
journalctl -u redis -n 50 --no-pager
# Hoặc trong Docker
docker logs <container_name> --tail 50
Tìm một trong các thông báo sau:
Can't save in background: fork: Cannot allocate memoryFailed opening the RDB file dump.rdb for saving: Permission deniedFailed opening the RDB file: No space left on device
Bước 2: Xác định nguyên nhân gốc rễ
Kiểm tra dung lượng đĩa
df -h
# Tập trung vào phân vùng nơi Redis lưu dữ liệu
# Mặc định: /var/lib/redis hoặc /etc/redis
df -h /var/lib/redis
Phân vùng đầy 100%? Đó chính là thủ phạm. Giải phóng dung lượng trước khi làm bất cứ điều gì khác.
Kiểm tra quyền thư mục dữ liệu Redis
# Tìm vị trí Redis đang lưu dữ liệu
redis-cli CONFIG GET dir
# Kiểm tra quyền sở hữu và phân quyền của thư mục đó
ls -la /var/lib/redis/
# Kết quả mong đợi: thư mục thuộc sở hữu của user redis
# drwxr-x--- 2 redis redis 4096 Mar 18 10:00 /var/lib/redis
Nếu thư mục thuộc sở hữu của root nhưng Redis chạy với user redis, mọi lần lưu đều sẽ thất bại trong im lặng.
Kiểm tra thư mục có tồn tại không
redis-cli CONFIG GET dir | tail -1 | xargs ls -la
Đường dẫn không tồn tại? Điều này thường xảy ra sau khi remount volume hoặc khởi động lại Docker. Redis không thể ghi vào nơi không tồn tại.
Bước 3: Sửa nhanh — mở khóa lệnh ghi ngay lập tức
Cần mở khóa ứng dụng trong khi tìm nguyên nhân thực sự? Chạy lệnh này:
redis-cli CONFIG SET stop-writes-on-bgsave-error no
Có hiệu lực ngay lập tức. Không cần khởi động lại. Redis sẽ chấp nhận lệnh ghi ngay cả khi lưu RDB thất bại.
Đây chỉ là giải pháp tạm thời — đừng coi nó là giải pháp lâu dài. Khi tắt tùy chọn này, Redis sẽ thầm lặng thất bại trong việc lưu dữ liệu và bạn sẽ không biết cho đến khi khởi động lại xóa sạch dataset của bạn.
Bước 4: Sửa vấn đề thực sự
Nếu đĩa đầy
# Tìm các file lớn đang chiếm dung lượng đĩa
du -sh /var/log/* | sort -hr | head -20
du -sh /var/lib/* | sort -hr | head -20
# Dọn log hệ thống cũ (ví dụ: chỉ giữ 200MB cuối)
journalctl --vacuum-size=200M
# Kiểm tra các file backup RDB còn sót lại
ls -lh /var/lib/redis/*.rdb
Nếu là vấn đề về quyền truy cập
# Sửa quyền sở hữu thư mục dữ liệu Redis
sudo chown -R redis:redis /var/lib/redis
# Sửa phân quyền
sudo chmod 750 /var/lib/redis
# Nếu file dump.rdb có quyền sở hữu sai
sudo chown redis:redis /var/lib/redis/dump.rdb
Nếu thư mục không tồn tại
# Tạo thư mục và đặt quyền sở hữu đúng
sudo mkdir -p /var/lib/redis
sudo chown redis:redis /var/lib/redis
sudo chmod 750 /var/lib/redis
Nếu chạy trong Docker với volume mount
Vấn đề quyền sở hữu volume mount là nguyên nhân của phần lớn lỗi Redis trên Docker. Khi bind-mount một thư mục host, thư mục đó thường thuộc sở hữu của root — Redis không thể ghi vào đó:
# docker-compose.yml
services:
redis:
image: redis:7-alpine
volumes:
- ./redis-data:/data
user: "999:999" # ID user redis trong image chính thức
command: redis-server --save 60 1 --loglevel warning
# Sửa quyền sở hữu phía host
sudo chown -R 999:999 ./redis-data
Bước 5: Bật lại tính năng lưu trữ và xác minh bản sửa lỗi
Đã xử lý nguyên nhân gốc rễ? Bật lại cài đặt an toàn:
redis-cli CONFIG SET stop-writes-on-bgsave-error yes
Kích hoạt lưu nền thủ công và xác nhận nó hoạt động:
# Kích hoạt lưu RDB nền
redis-cli BGSAVE
# Chờ một chút rồi kiểm tra timestamp
redis-cli LASTSAVE
# Chuyển Unix timestamp sang ngày có thể đọc được
date -d @<timestamp>
Xác nhận file dump thực sự đã được ghi xuống đĩa:
ls -lh $(redis-cli CONFIG GET dir | tail -1)/dump.rdb
Chạy kiểm tra ghi nhanh để đảm bảo mọi thứ hoạt động từ đầu đến cuối:
redis-cli SET testkey "hello"
redis-cli GET testkey
# Kết quả mong đợi: "hello"
Bước 6: Cố định bản sửa lỗi trong redis.conf
Các thay đổi qua CONFIG SET chỉ có hiệu lực trong runtime — chúng sẽ mất sau khi khởi động lại. Hãy cố định chúng vào redis.conf để tồn tại qua các lần reboot:
# Tìm file redis.conf của bạn
redis-cli CONFIG GET save
ls /etc/redis/redis.conf
# Các cài đặt quan trọng cần xem trong redis.conf:
# Nơi lưu file RDB — đảm bảo đường dẫn này tồn tại và có thể ghi
dir /var/lib/redis
# Lịch lưu RDB (mặc định lưu theo 3 điều kiện)
save 3600 1 # lưu sau 1 giờ nếu có ít nhất 1 key thay đổi
save 300 100 # lưu sau 5 phút nếu có ít nhất 100 key thay đổi
save 60 10000 # lưu sau 1 phút nếu có ít nhất 10000 key thay đổi
# Giữ là yes để lỗi không bị bỏ qua
stop-writes-on-bgsave-error yes
Reload sau khi chỉnh sửa — không cần khởi động lại hoàn toàn:
redis-cli CONFIG REWRITE # ghi cấu hình runtime hiện tại trở lại file
sudo systemctl reload redis # hoặc: redis-cli DEBUG RELOAD
Nếu bạn không cần RDB persistence
Dùng Redis thuần túy làm cache? Vô hiệu hóa persistence hoàn toàn và lỗi này sẽ không thể xảy ra:
# Vô hiệu hóa toàn bộ snapshot RDB
redis-cli CONFIG SET save ""
# Trong redis.conf, comment out hoặc xóa tất cả dòng save:
# save 3600 1
# save 300 100
# save 60 10000
Khi không có lịch lưu nào được cấu hình, Redis sẽ không bao giờ thực hiện lưu nền. Chỉ cần đảm bảo rằng việc mất dữ liệu khi khởi động lại là chấp nhận được cho trường hợp sử dụng của bạn trước khi thực hiện điều này.
Tóm tắt
- Lỗi MISCONF có nghĩa là
BGSAVEthất bại và Redis đã chặn lệnh ghi như một biện pháp an toàn. - Dùng
CONFIG SET stop-writes-on-bgsave-error nođể mở khóa ngay lập tức. - Sửa vấn đề thực sự: đĩa đầy, sai quyền trên thư mục dữ liệu, hoặc thư mục không tồn tại.
- Xác minh bằng
BGSAVErồiLASTSAVE— kiểm tra timestamp đã được cập nhật. - Lưu các thay đổi cấu hình vào
redis.confđể chúng tồn tại sau khi khởi động lại.

