Gramex Redis Cache随机抛出TypeError:无法序列化_thread.RLock对象求助
问题:Gramex Redis Cache随机抛出序列化异常
正在使用Gramex Redis Cache服务,偶尔会随机出现错误并在Gramex控制台抛出异常,请求协助解决。
错误日志
E 19-Jul 07:23:59 gramex:cache 8000 gramex.cache.open: <class 'gramex.services.rediscache.RedisCache'> cannot cache <tornado.template.Template object at 0x7f5cc43c1290> Traceback (most recent call last): File "/home/star/conda/lib/python3.7/site-packages/tornado/web.py", line 1704, in _execute result = await result File "/home/star/conda/lib/python3.7/site-packages/tornado/gen.py", line 769, in run yielded = self.gen.throw(*exc_info) # type: ignore File "/home/star/conda/lib/python3.7/site-packages/gramex/handlers/filehandler.py", line 188, in get yield self._get_path(self.root) File "/home/star/conda/lib/python3.7/site-packages/tornado/gen.py", line 762, in run value = future.result() File "/home/star/conda/lib/python3.7/site-packages/tornado/gen.py", line 234, in wrapper yielded = ctx_run(next, result) File "/home/star/conda/lib/python3.7/site-packages/gramex/handlers/filehandler.py", line 244, in _get_path raise HTTPError(FORBIDDEN, f'{self.file} not allowed') tornado.web.HTTPError: HTTP 403: Forbidden (/home/star/conda/lib/python3.7/site-packages/gramex/favicon.ico not allowed) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/star/conda/lib/python3.7/site-packages/gramex/cache.py", line 168, in open _cache[key] = cached File "/home/star/conda/lib/python3.7/site-packages/gramex/services/rediscache.py", line 58, in __setitem__ value = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) TypeError: can't pickle _thread.RLock objects
gramex.yaml配置
cache: memory: default: false redis: type: redis # path: $REDIS_CACHE_HOST:$REDIS_CACHE_PORT:$REDIS_CACHE_DB path: $REDIS_CACHE_HOST:$REDIS_CACHE_PORT:$REDIS_CACHE_DB:password=$REDIS_CACHE_PASSWORD size: 0 #GB cache default: true app: session: type: redis # Persistent multi-instance data store path: $REDIS_HOST:$REDIS_PORT:0:password=$REDIS_PASSWORD # Redis server expiry: 10 # Session cookies expiry in days purge: 86400 # Delete old sessions periodically (in seconds) domain: .mydomain.com url: show_daypart_data: pattern: /$YAMLURL/show_daypart_data handler: FormHandler kwargs: cors: true methods: $http_methods headers: $request_headers frm_30: url: $BigQ_CONN credentials_path: $CREDENTIAL_PATH state: my_utilities.cache_query(handler, '30 mi') queryfunction: star.get_show_daypart_query(handler, 'frm_period') modify: star.modify_show_daypart_data(handler, data) default: _limit: 450000 error: *API_ERROR
对应的Python函数(state参数使用)
def cache_query(handler, table): '''Runs a cache validation query''' args = handler.argparse( src={'default': 'any'}, view={'default': 'net'}) state = '' for tbl in table.split('+'): table_name = rds_tables[args.src][tbl] query = f"""SELECT CONCAT(year, '-', week) as week FROM {table_name} ORDER BY year DESC, week DESC limit 1""" try: val = REDIS_CACHE[str(query)] if not val: df = gramex.cache.query(query, db_engine) val = df.week.iloc[0] REDIS_CACHE[str(query)] = val state = '-' + val except Exception as error: app_log.error(f'Cache query failed ==> {error}') pass return state
解决方案
1. 修复favicon.ico的403错误
错误根源是Gramex尝试访问/home/star/conda/lib/python3.7/site-packages/gramex/favicon.ico时被禁止,触发HTTP 403异常。可通过以下方式解决:
- 在
gramex.yaml的url部分添加允许访问favicon.ico的规则:url: favicon: pattern: /favicon.ico handler: FileHandler kwargs: path: /path/to/your/favicon.ico # 指定项目内合法的favicon路径,如项目根目录下的文件 headers: Cache-Control: public, max-age=86400 - 或调整FileHandler权限配置,允许访问Gramex包内的favicon.ico(不推荐,建议使用自定义favicon)。
2. 解决Redis缓存无法序列化的问题
处理403异常时,Gramex尝试缓存tornado.template.Template对象,该对象包含无法被pickle序列化的_thread.RLock锁对象,导致报错。可通过以下方式处理:
- 排除特定路径的缓存:在
cache配置中,为favicon.ico这类静态资源路径禁用Redis缓存,改用内存缓存:cache: memory: default: false paths: /favicon.ico: true # 对favicon.ico使用内存缓存,避免Redis序列化问题 redis: type: redis path: $REDIS_CACHE_HOST:$REDIS_CACHE_PORT:$REDIS_CACHE_DB:password=$REDIS_CACHE_PASSWORD size: 0 default: true - 检查缓存内容:确保所有手动缓存的内容都是可序列化类型(当前
cache_query函数缓存的是字符串,这部分无问题,问题出在Gramex内部异常处理时的缓存操作)。
内容的提问来源于stack exchange,提问作者Nivedita Deshmukh
相关产品推荐
相关产品推荐

