在Celery Worker中使用requests_cache(SQLite后端)时触发MemoryError
解决Celery任务中requests_cache SQLite后端的MemoryError问题
环境与配置
- 设备:M1 MacBook
- 依赖版本:requests_cache1.1.0、celery5.3.4
- Celery配置:
broker_url="redis://localhost", result_backend="redis://localhost", task_ignore_result=True, - CachedSession配置:
CachedSession("http_cache.db")
问题现象
在Celery任务中通过CachedSession发起GET请求时,触发MemoryError,报错指向requests_cache/backends/sqlite.py第294行的查询语句,且该SQLite连接无法执行任何查询。但直接在Shell运行任务、使用普通requests库、切换至Redis后端时,任务均能正常执行。
解决思路
1. 适配SQLite的并发连接配置
Celery采用多进程/多线程模型,而SQLite默认连接并非线程安全,requests_cache的默认配置未适配该场景。可通过connect_args关闭线程安全检查,同时启用WAL模式提升并发性能:
from requests_cache import CachedSession session = CachedSession( "http_cache.db", connect_args={"check_same_thread": False}, wal=True # 启用Write-Ahead Logging模式,减少锁冲突 )
2. 为每个Celery任务创建独立Session实例
避免在任务外部全局创建CachedSession,而是在任务函数内部初始化,防止多进程共享同一个连接导致资源冲突:
from celery import Celery from requests_cache import CachedSession app = Celery('tasks', broker='redis://localhost') @app.task def fetch_cached_data(url): # 任务内部初始化独立Session session = CachedSession( "http_cache.db", connect_args={"check_same_thread": False}, wal=True ) response = session.get(url) return response.json()
3. 限制SQLite内存缓存大小
MemoryError可能源于SQLite内存缓存占用过高,可通过connect_args设置缓存上限:
session = CachedSession( "http_cache.db", connect_args={ "check_same_thread": False, "cache_size": -64 * 1024 # 限制缓存为64MB(负数单位为KB) }, wal=True )
4. 升级requests_cache版本
v1.1.0存在多进程场景下的SQLite兼容问题,升级至最新稳定版可修复部分已知bug:
pip install --upgrade requests_cache
内容的提问来源于stack exchange,提问作者sarartur
相关产品推荐
相关产品推荐

