You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django-redis设置timeout=None缓存JSON数分钟后自动清除如何解决

问题场景
  • 基于Django搭建了控制天文圆顶+家庭自动化的小型站点,项目启动阶段需要加载relays、conditions、homeautomation三个JSON配置文件
  • 为降低树莓派4B挂载SSD的频繁读写损耗,在apps模块启动时将解析后的JSON数据存入Redis;该Redis通过Docker部署,原本为项目Celery组件提供服务
  • 故障现象:写入Redis的JSON缓存仅能保留数分钟就会被自动清除
  • 预期需求:不需要Redis宕机数据持久化,不需要对接数据库能力,仅要求缓存数据在服务运行全周期常驻,不被自动清理

现有实现

缓存写入代码

cache.set("REDIS_ashtreeautomation_dict", dict, timeout=None)

Django缓存配置

CACHES = {
"default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://redis:6379",
    "OPTIONS": {
        "CLIENT_CLASS": "django_redis.client.DefaultClient",
        "SERIALIZER": "django_redis.serializers.json.JSONSerializer",
        "TIMEOUT": None
    }
}
}
排查与解决方案

你当前写的timeout=None配置在django-redis中本身就是代表永久不过期,语法和配置写法没有问题,缓存被自动清除基本都是以下几个原因导致,按优先级排查即可:

  1. 优先检查Redis内存淘汰策略(最高概率原因)
    多数默认拉取的Redis Docker镜像没有自定义配置时,内存达到maxmemory阈值后会触发默认淘汰规则,常见的allkeys-lru、volatile-lru策略会自动删除旧键腾空间,哪怕键被设置为永久有效期也会被清理。

    • 排查方式:进入Redis容器执行redis-cli CONFIG GET maxmemory-policy查看当前策略
    • 修复方式:将淘汰策略改为noeviction,该模式下Redis达到内存上限只会返回写入错误,不会删除任何已有键,完全匹配你的需求。临时生效可直接执行redis-cli CONFIG SET maxmemory-policy noeviction;要永久固定配置,在Docker启动Redis的命令/compose配置中追加启动参数--maxmemory-policy noeviction即可,同时可根据树莓派内存情况给Redis设置合理的maxmemory值(比如分配128-256M足够存储这类JSON配置),避免Redis吃光整机内存。
  2. 排查Redis库键冲突问题
    你的Redis同时承载Celery服务,默认Celery会使用Redis的db0库,如果Django缓存也用同一个db0,可能存在Celery过期清理逻辑误删、键名重复覆盖的问题。

    • 修复方式:给Django缓存单独分配独立的Redis逻辑库,将配置中LOCATION字段改为redis://redis:6379/1,使用db1和Celery默认的db0做逻辑隔离,避免服务间互相干扰。另外不要用Python内置类型名dict作为存储数据的变量名,容易触发序列化时的不可预期问题,将待存储的配置字典改为有实际语义的变量名(比如domotic_config)再传入cache.set即可。
  3. 验证永久有效期是否实际生效
    写入缓存后进入Redis执行redis-cli TTL REDIS_ashtreeautomation_dict,如果返回值为-1说明键确实被设置为永久有效期;如果返回其他正整数,说明存在全局中间件、其他启动逻辑覆写了缓存超时配置,全局搜索cache.set、缓存相关装饰器逻辑排查即可。


内容的提问来源于stack exchange,提问作者SgtBilko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:45:49