Lỗi gặp phải
Bạn chạy lệnh SELECT trong Redis — có thể trong code ứng dụng, thư viện client, hoặc trực tiếp trong redis-cli — và nhận được thông báo này:
127.0.0.1:6379> SELECT 16
(error) ERR DB index is out of range
Hoặc trong log ứng dụng:
ERR: Redis error: ERR DB index is out of range
Lỗi này thường xuất hiện sau khi thay đổi cấu hình, di chuyển sang Redis server mới, hoặc khi ai đó tăng chỉ số database trong codebase mà không biết rằng server chưa được cấu hình tương ứng.
Nguyên nhân
Redis hỗ trợ nhiều database logic trong một instance. Mặc định có 16 database, được đánh số từ 0 đến 15. Lệnh SELECT dùng để chuyển đổi giữa các database này.
Lỗi xảy ra ngay khi bạn truyền vào chỉ số bằng hoặc lớn hơn số lượng database đã cấu hình. Với mặc định là 16, lệnh SELECT 16 sẽ thất bại — chỉ số hợp lệ cao nhất chỉ là 15.
Một số nguyên nhân phổ biến:
- Code của bạn tham chiếu đến chỉ số database 16 hoặc cao hơn, nhưng Redis mặc định chỉ có tối đa chỉ số 15
- Redis server mới được khởi tạo với giá trị
databasesthấp hơn — đôi khi chỉ làdatabases 1 - Dịch vụ managed như Redis Cloud, ElastiCache, hoặc Upstash chỉ cho phép dùng database
0 - Redis đang chạy ở chế độ Cluster, vốn giới hạn cứng chỉ dùng database
0
Cách xử lý nhanh: Kiểm tra chỉ số đang SELECT
Trước tiên, xác nhận chính xác giới hạn trên instance của bạn:
redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> SELECT 0 # thành công
127.0.0.1:6379> SELECT 15 # thành công (chỉ số hợp lệ cuối cùng với cấu hình mặc định)
127.0.0.1:6379> SELECT 16 # thất bại → ERR DB index is out of range
Sau đó kiểm tra số lượng database đã cấu hình:
127.0.0.1:6379> CONFIG GET databases
1) "databases"
2) "16"
Kết quả 1 nghĩa là chỉ có database 0. Kết quả 16 nghĩa là chỉ số hợp lệ từ 0 đến 15.
Đang dùng thư viện client? Tìm nơi tham số db được thiết lập:
# Python (redis-py)
import redis
r = redis.Redis(host='localhost', port=6379, db=16) # ← dòng này sẽ thất bại
// Node.js (ioredis)
const redis = new Redis({ host: 'localhost', port: 6379, db: 16 }); // ← lỗi tương tự
Đổi db về giá trị trong khoảng cho phép — thường từ 0 đến 15 là tất cả những gì bạn có.
Sửa cấu hình Redis: Tăng số lượng database
Cần chỉ số cao hơn 15? Tăng giá trị databases trong file redis.conf.
Bước 1 — Tìm file redis.conf
# Các vị trí thường gặp
/etc/redis/redis.conf
/etc/redis.conf
/usr/local/etc/redis.conf
# Hoặc tìm qua tiến trình đang chạy
ps aux | grep redis
Bước 2 — Chỉnh sửa directive databases
sudo nano /etc/redis/redis.conf
# Tìm dòng này:
databases 16
# Tăng lên giá trị bạn cần:
databases 32
Bước 3 — Khởi động lại Redis
# systemd
sudo systemctl restart redis
# init cũ
sudo service redis-server restart
Bước 4 — Xác nhận thay đổi đã áp dụng
redis-cli CONFIG GET databases
# Kết quả mong đợi:
# 1) "databases"
# 2) "32"
# Kiểm tra lệnh trước đó đã thất bại
redis-cli SELECT 16
# Kết quả mong đợi: OK
Không có tùy chọn restart? Setting này không hỗ trợ thay đổi live
CONFIG SET cho phép thay đổi nhiều cài đặt Redis ngay lập tức, nhưng databases không nằm trong số đó. Đừng mất công thử:
127.0.0.1:6379> CONFIG SET databases 32
(error) ERR Unknown option or number of arguments for CONFIG SET - 'databases'
Bắt buộc phải restart. Hãy lên lịch một cửa sổ bảo trì ngắn, hoặc promote một replica trước để giữ hệ thống hoạt động trong khi primary khởi động lại.
Docker: Truyền setting qua tham số dòng lệnh
Đang chạy Redis trong Docker mà không mount file config? Bỏ qua file config và truyền flag trực tiếp:
docker run -d \
--name redis \
-p 6379:6379 \
redis:7 redis-server --databases 32
Với Compose:
services:
redis:
image: redis:7
command: redis-server --databases 32
ports:
- "6379:6379"
Managed Redis (ElastiCache, Upstash, Redis Cloud)
Các dịch vụ managed giới hạn bạn chỉ dùng database 0. Không có ngoại lệ. Không có panel cấu hình nào để thay đổi điều này — đây là ràng buộc cấp nền tảng được tích hợp vào kiến trúc của các dịch vụ này.
Giải pháp thực tế là dùng key namespacing. Thay vì phân chia dữ liệu theo database, hãy thêm prefix vào key:
# Cách cũ — không hoạt động trên managed Redis:
SELECT 2
SET user:123 "alice"
# Cách phù hợp với managed Redis:
SET app2:user:123 "alice"
Các key như app1:user:123 và app2:user:123 cùng tồn tại trong database 0 mà không xung đột. Đây chỉ là thay đổi nhỏ trong quy ước đặt tên, không phải thiết kế lại.
Redis Cluster: SELECT không được hỗ trợ
Chế độ Cluster không hỗ trợ nhiều database — chỉ database 0 hoạt động. Lý do: Cluster phân mảnh dữ liệu qua các node bằng hash slot, và việc hỗ trợ nhiều database sẽ phá vỡ hoàn toàn mô hình này. Bất kỳ lệnh SELECT N nào với N khác 0 đều sẽ trả về lỗi này.
Với Cluster, hãy loại bỏ tất cả lệnh SELECT và chuyển sang key namespacing (tương tự như cách dùng với managed Redis ở trên).
Kiểm tra lại sau khi sửa
Sau khi áp dụng bản sửa lỗi, hãy kiểm tra nhanh theo các bước sau:
# 1. Xác nhận số lượng database
redis-cli CONFIG GET databases
# 2. Kiểm tra lệnh SELECT trước đó đã thất bại
redis-cli SELECT 16
# Kết quả mong đợi: OK
# 3. Ghi và đọc một key trong database mới
redis-cli -n 16 SET test_key "hello"
redis-cli -n 16 GET test_key
# Kết quả mong đợi: "hello"
# 4. Khởi động lại ứng dụng và xác nhận lỗi không còn trong log

