Docker Compose部署Memcached返回None问题求助
嘿,我来帮你梳理排查这个问题!你遇到的缓存一直返回None的情况,大概率是几个常见的配置或代码细节出了问题,咱们一步步来拆解:
1. 优先检查Django缓存配置是否指向正确的Memcached服务
因为用了Docker Compose,容器之间的通信不能用localhost——在Django容器里,localhost指的是容器自身,而非宿主机或Memcached容器。你需要用Docker Compose中Memcached服务的名称来配置缓存地址:
假设你的docker-compose.yml里Memcached服务名为memcached,那Django的settings.py里缓存配置应该是这样:
CACHES = { 'default': { # 如果你用的是pymemcache后端(推荐) 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': 'memcached:11211', # 这里用服务名+端口,不是localhost # 可选:如果需要序列化支持,加上这个 'OPTIONS': { 'serializer': 'django.core.cache.backends.memcached.PickleSerializer', } } }
如果用的是旧版的MemcachedCache后端,格式也类似:'LOCATION': ['memcached:11211']。
2. 你缓存的QuerySet对象无法直接序列化
看你代码里直接把CategoryNews.objects.all()(一个QuerySet)存进了缓存,但QuerySet是懒加载的数据库查询对象,Memcached要求缓存内容必须是可序列化的(比如pickle或JSON格式)。直接存QuerySet会导致缓存写入失败,自然读的时候返回None。
解决办法是把QuerySet转换成可序列化的列表:
from django.core.cache import cache def show_category(request): cache_key = 'category_names' cache_time = 1800 result = cache.get(cache_key) print(result) if result is None: # 把QuerySet转成列表再缓存 result = list(CategoryNews.objects.all()) cache.set(cache_key, result, cache_time) # 可以加个调试打印,确认写入是否成功 print(f"缓存写入后读取:{cache.get(cache_key)}") return render(request, ...)
3. 验证Memcached容器是否可被Django容器访问
进入Django容器,手动测试和Memcached的连接:
# 进入Django容器(替换成你的容器名) docker exec -it your-django-container-name bash # 用telnet测试连接Memcached服务 telnet memcached 11211 # 如果连接成功,输入stats查看Memcached状态,确认服务正常 stats
如果连接失败,检查docker-compose.yml里Memcached的配置:
services: memcached: image: memcached:latest ports: - "11211:11211" django-app: build: . depends_on: - memcached # 其他配置...
注意depends_on只保证启动顺序,不保证Memcached完全就绪,但Memcached启动很快,这个问题一般不影响。
4. 其他可能的小问题
- 缓存键冲突:有没有其他地方用了相同的
category_names键,或者有定时任务在清除缓存?可以临时换个键名测试,比如test_category_names。 - Memcached内存不足:默认Memcached只有64MB内存,数据量超过会自动淘汰旧缓存。可以在
docker-compose.yml里调整内存:memcached: image: memcached:latest command: memcached -m 256 # 设置为256MB内存 ports: - "11211:11211"
先从配置和序列化这两个最常见的点入手,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者Serg Bombermen

