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

使用Django Redis缓存重启manager.py后对象属性丢失问题排查

问题原因分析

1. 类属性与实例属性混淆

你定义的CrossSectionFactory中,cross_section_sequence是类属性,所有该类的实例共享这个字典。调用add方法修改它时,实际修改的是类本身的属性,而非单个实例独有的属性。而Django Redis缓存仅序列化实例对象,类属性不会被存入缓存——缓存只保存实例自身的状态,不关联类的全局状态。

2. 进程重启后的类状态重置

重启manager.py后,新进程会重新加载所有类定义,CrossSectionFactory的cross_section_sequence会被重新初始化为空字典。此时从缓存反序列化出来的Analyzer实例,其cross_section_factory仍引用新进程中的类属性,自然会看到空字典。

3. 旧缓存键的数据干扰

旧缓存键对应的是进程重启前的实例状态,但该实例关联的类属性状态并未被缓存。更换缓存键后,新缓存的是进程重启后创建的实例(此时实例已生成独立的属性状态),因此能正常读写。

解决方法

1. 将类属性改为实例属性

修改CrossSectionFactory,在__init__方法中初始化cross_section_sequence为实例属性,确保每个实例拥有独立的字典:

class CrossSectionFactory(LoggerMixin):
    def __init__(self, logger=None, **kwargs):
        super().__init__(logger=logger, **kwargs)
        self.cross_section_sequence = {}  # 改为实例属性

    def add(self, date):
        cross_section = CrossSection()
        self.cross_section_sequence[date] = cross_section

这样每个CrossSectionFactory实例的字典都是独立的,序列化时会将该属性一并存入缓存,重启进程后反序列化的实例能保留原有数据。

2. 清理旧缓存

删除之前的旧缓存键,避免反序列化出关联旧类状态的实例:

cache.delete("analyzer:1")

3. 验证序列化兼容性

确保自定义类(CrossSection、CrossSectionFactory、Analyzer)支持pickle序列化(Django Redis缓存默认用pickle)。如果LoggerMixin包含不可序列化的属性(如文件句柄、网络连接),需在类中定义__getstate__和__setstate__方法处理这些属性的序列化逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:07:44