[英]Should django model object instances be passed to celery?
# models.py
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
text_blob = models.CharField(max_length=50000)
# tasks.py
import celery
@celery.task
def my_task(person):
# example operation: does something to person
# needs only a few of the attributes of person
# and not the entire bulky record
person.first_name = person.first_name.title()
person.last_name = person.last_name.title()
person.save()
在我的應用程序的某個地方我有類似的東西:
from models import Person
from tasks import my_task
import celery
g = celery.group([my_task.s(p) for p in Person.objects.all()])
g.apply_async()
如何有效且均勻地將Person記錄分發給在多台機器上運行的工作人員?
這可能是一個更好的主意嗎? 如果Person有幾百萬條記錄,難道不會壓倒db嗎?
# tasks.py import celery from models import Person @celery.task def my_task(person_pk): # example operation that does not need text_blob person = Person.objects.get(pk=person_pk) person.first_name = person.first_name.title() person.last_name = person.last_name.title() person.save() #In my application somewhere from models import Person from tasks import my_task import celery g = celery.group([my_task.s(p.pk) for p in Person.objects.all()]) g.apply_async()
我相信通過PK而不是整個模型對象更好更安全。 由於PK只是一個數字,序列化也更簡單。 最重要的是,您可以使用更安全的sarializer(json / yaml而不是pickle),並且可以放心,您在序列化模型時不會遇到任何問題。
由於該文章說:
由於Celery是一個分布式系統,因此您無法知道在哪個進程中運行,甚至無法知道運行任務的機器。 因此,您不應該將Django模型對象作為參數傳遞給任務,而是從數據庫中重新獲取對象幾乎總是更好,因為可能存在競爭條件。
是。 如果數據庫中有數百萬條記錄,那么這可能不是最好的方法,但由於你必須經歷所有數百萬條記錄,那么無論你做什么,你的數據庫都會受到很大影響。硬。
以下是一些替代方案,其中沒有一個我稱之為“更好”,只是不同。
./manage.py my_task a
會更新姓氏以“a”開頭的所有記錄。 顯然你必須多次運行才能通過整個數據庫 請記住,.save()將更難“擊中”數據庫,然后實際選擇數百萬條記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.