
django 项目通过 docker 集成 redis 后,`redis-cli` 默认连接 db0 为空,而 django 缓存实际写入的是 db1(或其他非默认库),需正确指定数据库编号并确认缓存后端配置。
在 Django + Docker + Redis 的典型部署中,redis-cli 连接后执行 keys * 返回空结果(仅看到 Celery 的 Kombu 绑定键),并不意味着 Redis 没有数据,而是因为 Django 缓存与 Celery 使用了不同的 Redis 数据库编号(db index),且 Django 缓存后端未显式配置导致回退到本地内存缓存。
✅ 核心原因与修复步骤
1. 确认 Django 缓存后端已正确配置
Django 默认的 CACHES 配置使用 LocMemCache(进程内内存缓存),完全不经过 Redis。必须显式配置为 Redis 后端:
# settings.py
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://redis:6379/1", # 注意:使用 db1(非默认 db0)
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}⚠️ 若 LOCATION 写成 redis://redis:6379/0,则与 Celery 共用 db0 —— 但 Celery 通常只写 _kombu.binding.* 类键,而 Django 缓存键(如 :1:my_key)仍可能被写入,需配合 -n 0 查看;更推荐分离数据库避免冲突,故推荐 /1。
2. 使用 redis-cli -n 连接到正确的数据库
redis-cli 默认连接 db0,而 Django 缓存写入的是 db1(由 LOCATION 中的 /1 指定)。因此需显式指定数据库:
# 进入 Redis 容器并连接 db1 docker exec -it redis redis-cli -n 1 # 在 redis-cli 中查看所有键 127.0.0.1:6379> keys * 1) ":1:my_cached_value" 2) ":1:session:abc123..." # 获取缓存值(注意前缀 :1: 是 django-redis 自动添加的 db 标识) 127.0.0.1:6379> get ":1:my_cached_value" "\"cached_data\""
3. 验证缓存是否真正生效
在 Django Shell 中测试缓存读写:
# python manage.py shell
>>> from django.core.cache import cache
>>> cache.set('test_key', 'hello_redis', timeout=300)
True
>>> cache.get('test_key')
'hello_redis'随后立即在 redis-cli -n 1 中执行 keys *,应能看到类似 :1:test_key 的键。
4. (可选)统一环境变量管理
为避免硬编码,建议在 .env 中定义 Redis DB 号,并在 settings.py 中读取:
# .env REDIS_URL=redis://redis:6379/1
# settings.py
import os
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": os.environ.get("REDIS_URL", "redis://redis:6379/1"),
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
}
}✅ 总结
- ❌ 错误认知:“redis-cli 看不到数据 = Redis 没存进去”
- ✅ 正确排查路径:
① 检查 CACHES['default']['BACKEND'] 是否为 RedisCache(非 LocMemCache);
② 核对 LOCATION 中的数据库编号(如 /1);
③ 使用 redis-cli -n 1 连接对应 DB;
④ 通过 Django Shell 验证缓存读写闭环。
完成上述配置后,redis-cli -n 1 keys * 将清晰显示 Django 缓存键,实现可观测、可调试、可运维的 Redis 缓存集成。










