Django:如何让services.py中的load_model方法始终保持缓存可用
解决方案
问题分析
你遇到的核心问题是:lru_cache的LRU淘汰策略会因API调用频率低清除加载好的模型实例;而cache_page用于缓存视图的HTTP响应,无法缓存模型对象,因此对你的场景无效。
下面提供几个可行的解决方案:
方案1:修改lru_cache参数禁用LRU淘汰
将lru_cache的maxsize设为None,缓存不会因LRU策略被清除,只要服务进程运行,模型实例就会一直保留在内存中(需确保模型内存占用在服务器承受范围内)。
修改services.py:
from functools import lru_cache from keyphrasetransformer import KeyPhraseTransformer @lru_cache(maxsize=None) # 禁用LRU淘汰,缓存所有调用结果 def load_model(): kp_model = KeyPhraseTransformer() return kp_model
该方案代码改动最小,适配你的低调用频率场景。
方案2:服务启动时预加载模型(推荐)
直接在Django应用启动阶段加载模型,彻底避免第一次请求的等待时间。
- 修改你的app下的
apps.py:
from django.apps import AppConfig from .services import load_model class ExtractKeyphraseAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = '你的app名称' # 替换为实际的app名称 def ready(self): # 应用启动时预加载模型,后续请求直接复用 load_model()
- 在项目的
settings.py中,将你的app配置替换为上述类:
INSTALLED_APPS = [ # ... 其他已安装的app '你的app名称.apps.ExtractKeyphraseAppConfig', ]
服务启动时会自动执行load_model(),后续所有请求直接使用缓存好的模型实例。
方案3:用单例模式确保模型全局唯一
通过单例类实现模型的全局唯一实例,确保每次调用load_model()都返回同一个对象,不会被清除。
修改services.py:
from keyphrasetransformer import KeyPhraseTransformer class KeyPhraseModelSingleton: _instance = None @classmethod def get_instance(cls): if cls._instance is None: cls._instance = KeyPhraseTransformer() return cls._instance def load_model(): return KeyPhraseModelSingleton.get_instance()
该方案与方案1效果类似,但无需依赖lru_cache,逻辑更直观。
为什么cache_page无效?
cache_page是Django的视图缓存装饰器,它缓存的是视图返回的HTTP响应内容(如JSON数据),而非load_model()返回的模型对象,因此无法解决模型加载耗时的问题。
内容的提问来源于stack exchange,提问作者Tyler Kim
相关产品推荐
相关产品推荐

