我有一个应用程序通过上传视图获取csv文件,它将文件中的数据读入列表,然后将列表传递给芹菜任务,然后任务使用生成器函数将数据拆分为200个块(进行一些预处理以确保没有重复)。然后将这些块传递给任务集,处理块并将行写入数据库,然后子任务将写入的行的结果等传递给主任务,以记录完整任务集的日志。
我在加载大量数据时遇到问题,1个任务写入一大块200行的数据随机冻结,如果我终止此任务,则队列继续处理。在使用本地运行的db和celery进行测试时从未发生这种情况,所以我假设它是某种mysql连接问题,celery.log和mysql日志都没有透露任何东西,由于我缺乏经验,我不完全确定如何排除故障。
我正在运行django,mysql,rabbitmq用于任务队列和结果,其中1个服务器用于db,webserver,另一个用于任务处理(2个运行ubuntu服务器12.04的AWS EC2)。
我的代码:
#views.py
reader = csv.reader(request.FILES['f'], delimiter=',', quotechar='"')
#Skip the header
reader.next()
uploaddata = [row for row in reader]
LegacyUploadManager.delay(uploaddata, log.pk)
#tasks.py
class LegacyUploadManager(Task):
"""
Task to take uploads, split into smaller tasks and manage
"""
def run(self, f, logpk):
#Create chunk generator to split chunks into sets of 200
ChunkGen = UploadChunkGen(f, 200)
#Generate chunks and create a taskset of chunk tasks
self.tasks = []
for chunk in ChunkGen:
self.tasks.append(LegacyUploader.subtask([chunk]))
#create taskset and start processing
job = TaskSet(self.tasks)
result = job.apply_async()
#Wait for tasks to complete
while result.waiting():
time.sleep(10)
#Write results to database via ImportLogger task
ImporterLogger.delay(logpk, result.join())
class LegacyUploader(Task):
"""
Task for uploading products imported from ESP via a full product layout.
"""
def run(self, f):
for row in f:
Product.objects.create(row)
我想我只需要在'job.apply_async()'中添加'timeout = ....'参数,但我不确定这样做的后果。即我会丢失在超时任务上未处理的所有行,还是会在任务超时之前写入数据库的行再次写入?