2016-03-28 8 views
0

Auf unserer Website wir stündlich Berichte für unsere Nutzer, unsere erste Lösung war diese erstellt werden sollen (ich bin mit Sellerie für die):effiziente Art und Weise mit Sellerie gesamte Tabelle scannen

hier ist das, was ich benutze für die Erstellung von Bericht für einen einzelnen Benutzer:

@app.task 
def create_report(user): 
    # this method creates report for given user 
    pass 

und dann habe ich diese Crontask, Sellerie läuft diese Aufgabe alle 60 Minuten:

@app.task 
def report_cron(): 
    for user in User.objects.all(): 
     create_report.delay(user) 

diese soultion fügt die ganze Tabelle von Benutzern in Sellerie Warteschlange (wir benutzen rabbitmq).

derzeit funktioniert diese Lösung gut (wir haben nicht viele Benutzer), aber können Sie mit einer besseren Lösung für dieses Problem helfen?

Antwort

1

Ich werde einige Dinge erraten müssen, weil Ihre Frage nicht viele Informationen enthält.

Angenommen, Ihr Bericht ist ein Modell, Sie könnten sie erstellen, ohne sie zu speichern, und dann bulk_create verwenden, um eine einzige Anforderung zu haben.

Nehmen wir an, Sie müssen auf Fremdschlüssel in Ihrem Benutzermodell zugreifen, sollten Sie select_related und prefetch_related verwenden, um Ihre Anfrage zu optimieren. Im Idealfall sollte Ihre Aufgabe nicht mehr als eine Anfrage für alle Ihre Benutzer plus eins für viele bis viele Felder, die Sie benötigen, und eine für die Erstellung aller Berichte.

Das ist alles, was ich ohne weitere Informationen empfehlen könnte. Vielleicht sollten Sie bei jeder Benutzer-Iteration einen Test hinzufügen, um sicherzustellen, dass Ihre Aufgabe nicht länger als eine Stunde dauert. Sie sind also nicht überrascht, wenn das passiert.

+0

danke für die Antwort. Ich denke, ich habe mein Problem nicht gut genug beschrieben. das Erstellen eines einzelnen Berichts ist nicht mein Hauptanliegen (es kann so viel Zeit und db Abfragen dauern wie es will) Problem ist jedes Mal, wenn Sellerie läuft 'report_cron' es wird die ganze Tabelle der Benutzer lesen und schieben Sie es auf Rabbitmq Warteschlange. Der Prozess des Lesens der gesamten Tabelle und des Push-Vorgangs in die Warteschlange kann zeit- und ressourcenintensiv sein. Ich wollte wissen, wie ich mit dieser Seite des Problems umgehen kann. – aliva

2

Es ist nichts besonders falsch mit diesem Ansatz, obwohl es hängt davon ab, wie lange jeder Bericht dauert. Zum Beispiel, wenn es eine Millisekunde pro Bericht benötigt, dann wird es den größten Teil der gesamten Zeit damit verbringen, Nachrichten auf und von der Warteschlange zu setzen und db-Verbindungen herzustellen. Über die einzige Optimierung, die ich vornehmen würde, ist die Stapelverarbeitung. Sie können also einstellen, wie viele Berichte pro Aufgabe generiert werden. Dann könnten Sie verschiedene Losgrößen ausprobieren, um das beste Gleichgewicht zu finden.

Mit Warteschlangen ist dieser Weg auch großartig, da Sie durch Hinzufügen weiterer Worker skalieren können.

Der Nachteil ist, dass die Berichte nicht genau stündlich sind, abhängig davon, wie lange Nachrichten darauf warten, verarbeitet zu werden.

+0

danke für die Antwort. Batching ist eine gute Idee, an die ich nicht gedacht habe. Erstellen von Berichten ist keine Aktion mit hoher Priorität, also bestehe ich nicht darauf, sie genau nach 60m zu erstellen (es kann variieren) – aliva

+0

wie Sie erwähnt ganze Benutzer Tabelle in Warteschlange einfügen kann ein wenig Zeit dauern. Wenn ich meinen Code lokal mit vielen Benutzern (5 Millionen) teste, reagiert mein System für ein paar Sekunden nicht mehr (wenn Sellerie Benutzer zur Warteschlange hinzufügt) ist unsere aktuelle Benutzerbasis viel weniger, aber wie vermeide ich diese Ausfallzeit in Zukunft? – aliva

+0

Verwenden Sie eine andere Sellerieaufgabe, um die anderen Aufgaben zu erstellen. Sie möchten Ihre lang laufenden Aufgaben in den Hintergrund rücken.Sie haben also eine Aufgabe, die Sie in Ihrem Hauptthread erstellen (die Erstellung von 1 Aufgabe ist schnell), die bei der Ausführung alle anderen Aufgaben erstellt (das dauert eine Weile, aber es ist egal, weil es als Sellerie-Aufgabe ausgeführt wird und nicht gehalten wird) alles andere bis). – Darren

Verwandte Themen