我正在使用Celery为Flask应用程序运行后台任务。 Celery将Redis用作其经纪人和其结果后端。后台任务返回一个相当大的自定义对象(约100MB)。但是,该任务从未完成,最终Celery引发了源自Kombu的MemoryError:
[2018-07-18 13:10:26,686: ERROR/ForkPoolWorker-1] Task CeleryTasks.VSIndexer[ee2a9222-1d04-4a58-859a-d04512b3fee1] raised unexpected: EncodeError(MemoryError(),)
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/kombu/serialization.py", line 50, in _reraise_errors
yield
File "/usr/lib/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
payload = encoder(data)
File "/usr/lib/python3.6/site-packages/kombu/serialization.py", line 350, in pickle_dumps
return dumper(obj, protocol=pickle_protocol)
MemoryError
我尝试创建返回大字符串的任务,并且看起来可以正常工作(我得到类似的MemoryErrors,字符串大小约为1GB)。我还可以返回较小的自定义类(我正在用pickle进行序列化)。但是对于大型对象,Celery的AsyncResult.ready()
永远都不是正确的,也就是说,任务始终处于待处理状态。
我觉得Kombu在引擎盖下使用Pipes,并且Pipe缓冲区太小,无法容纳这么大的物体。
是否有增加其大小的方法,还是必须减小从Celery任务传回的对象的大小?也许正在发生其他事情?