Schnelles Hinzufügen mehrerer Elemente (1000 / Sek.) zu einer Sidekiq-Warteschlange?

8

Mir ist klar, dass es eine Option push_bulk für sidekiq gibt, aber ich werde momentan durch die Latenz auf redis beschränkt, so dass die Weiterleitung mehrerer Elemente über push_bulk immer noch nicht schnell genug geht (nur etwa 50 / s).

Ich habe versucht, die Anzahl der Redis-Verbindungen wie folgt zu erhöhen:

%Vor%

Und feuern Sie dann separate Threads (Thread.new) ab, um tatsächlich asasync für die verschiedenen Objekte auszuführen. Interessant ist, dass jeder Thread, der nicht der erste Thread ist, NIEMALS in die sidekiq-Queue geworfen wird, als ob sie vollständig ignoriert würden.

Weiß jemand einen besseren Weg, dies zu tun?

Bearbeiten: Hier ist die push_bulk-Methode, die ich versuchte, die eigentlich langsamer ist:

%Vor%

Danke!

    
Geesu 18.12.2013, 21:25
quelle

2 Antworten

11

Sie möchten push_bulk verwenden. Sie sind durch die Latenz- / Umlaufzeit beschränkt, um Elemente in die Redis-Warteschlange zu schreiben, die sidekiq unterstützt.

Sie verwenden mehrere Threads / Verbindungen, um ein langsames Netzwerk zu überwinden, wenn Sie wirklich zusätzliche Netzwerk-Roundtrips entfernen sollten.

Angenommen, Sie versuchen, 20k UserWorker Jobs zu enqueueing, die ein user_id übernehmen:

Sie würden einen einzelnen Job in die Warteschlange stellen über:

%Vor%

... welches zu:

passt %Vor%

Also ist die push_bulk Version für 20k user_ids:

%Vor%

Damit werden 20k redis-Anrufe in 20 redis-Anrufe umgewandelt, mit einer durchschnittlichen Umlaufzeit von 5ms (optimistisch), das entspricht 1sec gegenüber 100 Sekunden. Ihre Laufleistung kann variieren.

BEARBEITEN: Kommentatoren scheinen über das Verhalten des Sidekiq / Redis-Clients für Massen-Enqueuing-Daten verwirrt zu sein.

Die Methode Sidekiq::Client.push_bulk() benötigt ein Array von Jobs, die enqueud werden sollen. Sie übersetzt diese in Sidekiq-Job-Payload-Hashes und ruft dann SideKiq::Client.raw_push() auf, um diese Payloads an Redis zu liefern. Siehe Quelle: Ссылка

SideKiq::Client.raw_push() verwendet eine Liste von Sidekiq-Hash-Nutzdaten, konvertiert sie in JSON und führt dann einen Befehl redisis MULTI aus, der zwei redis-Befehle kombiniert. Zuerst fügt es der Zielwarteschlange die Liste der aktiven Warteschlangen hinzu (redis SADD ) und schiebt dann alle Job-Nutzdaten an das Zielwartelisten-Wiedergabelistenobjekt (redis LPUSH ). Dies ist ein einzelner Redis-Befehl, der zusammen in einer einzelnen Redis-Atomgruppe ausgeführt wird.

Wenn dies immer noch langsam ist, haben Sie wahrscheinlich andere Probleme (langsames Netzwerk, überladener Redis-Server usw.).

    
Winfield 19.12.2013 21:31
quelle
4

@ Winfields Antwort ist richtig, und er hat absolut Recht mit Latenz. Die richtige Syntax ist jedoch tatsächlich wie folgt:

%Vor%

Vielleicht hat es sich im letzten Sidekiq geändert (ich war zu faul, das zu überprüfen), aber das ist jetzt die richtige Syntax.

    
Michael Y. 05.05.2016 16:27
quelle

Tags und Links