我在mongoDB集合中有几十万个文档可访问,这些文档遵循一个名为MyDoc的MongoEngine模式。每个文档都要运行一些东西(让我们称之为“我的操作”)。另外,我的操作需要(只读取,不改变)一个名为data_dict的有序dict,通过create_data_dict函数构造。我希望能够通过芹菜工人并行地运行我的操作。在
设置包括django,mongo,mongoengine和芹菜。在
选项1:@celery.task()
def my_operation(my_doc_list):
data_dict = create_data_dict()
for doc in my_doc_list:
do_something_to_doc(data_dict, doc)
doc.save()
def create_data_dict():
#blah blah blah
return data_dict
#So I run everything like this:
batch_size = len(MyDoc.objects)/no_of_celery_workers
for b in xrange(0, len(MyDoc.objects), batch_size):
my_operation.delay(MyDoc.objects[b:b+batch_size])
选项2:my_操作接受data-tu-dict和MyDoc实例
^{pr2}$
选项3:@celery.task()
def my_operation(my_doc):
data_dict = create_data_dict()
do_something_to_doc(data_dict, my_doc)
my_doc.save()
def create_data_dict():
#blah blah blah
return data_dict
#So I run everything like this:
celery.group([my_operation.s(my_doc) for my_doc in MyDoc.objects]).apply_async()
选项4:@celery.task()
def my_operation(my_doc):
data_dict = get_data_dict()
do_something_to_doc(data_dict, my_doc)
my_doc.save()
def create_data_dict():
#blah blah blah
return data_dict
def get_data_dict():
data_dict = cache.get("data_dict")
if data_dict is None:
data_dict = create_data_dict()
cache.set("data_dict", data_dict)
return data_dict
#So I run everything like this:
celery.group([my_operation.s(my_doc) for my_doc in MyDoc.objects]).apply_async()
如果选项1起作用,我可能不会问这个问题,但遗憾的是,我不能将queryset的响应片或querysets本身传递给芹菜工人,因为它们不可腌制。这就是回溯的意思。在
有了Option2,我会在每个任务中传递数据字典,这听起来不太吸引人。如果我在多台机器上运行celery workers,(我确实打算这样做)数据字典,基本上只需要传递一次,就会毫无价值地消耗大量网络。在
在Option3的情况下,每个文档都会重新创建数据字典,这似乎是对处理能力的巨大浪费。在
选项4:我使用缓存来备份数据字典,而不是重新计算或与每个文档一起重新传输。这听起来是最好的主意,但有一个陷阱。下一次我想对所有MyDocs执行“u”操作时,我希望重新计算数据字典,而不管它是否在缓存中。有没有办法做到这一点?在
问题是:
最好的办法是什么?在