warum ist es so langsam mit 100.000 Datensätze bei der Verwendung von Pipeline in Redis?

8

Es wird gesagt, dass pipeline ein besserer Weg ist, wenn viele set/get in redis benötigt werden, das ist also mein Testcode:

%Vor%

Wenn ich es ausführte, gibt es keine Antwort mit diesem Programm für eine Weile, aber wenn ich nicht mit pipe arbeite, dauert es nur 20073 ms, also bin ich verwirrt, warum es noch besser ist ohne pipeline und wie eine breite Lücke!

Danke für die Antwort, ein paar Fragen, wie berechnen Sie 6MB Daten? Wenn ich 10K Daten sende, ist die Pipeline immer schneller als der normale Modus, aber mit 100k, Pipeline würde keine Antwort.Ich denke, 100-1000 Operationen ist eine empfehlenswerte Wahl wie unten gesagt.Ist es an JIT da ich es nicht verstehe?

    
znlyj 22.05.2013, 16:49
quelle

1 Antwort

14

Bevor Sie einen solchen Benchmark (und insbesondere einen Benchmark mit der JVM) schreiben, müssen Sie einige Punkte beachten:

  • Auf den meisten (physischen) Maschinen kann Redis beim Pipelining mehr als 100 KByte pro Sekunde verarbeiten. Ihr Benchmark behandelt nur 100K-Artikel und reicht daher nicht lange genug aus, um aussagekräftige Ergebnisse zu erzielen. Außerdem haben die aufeinander folgenden Phasen der JIT keine Zeit für einen Anstoß.

  • Die absolute Zeit ist keine sehr relevante Metrik. Das Anzeigen des Durchsatzes (d. H. Die Anzahl der Operationen pro Sekunde), während der Benchmark mindestens 10 Sekunden lang läuft, wäre eine bessere und stabilere Metrik.

  • Ihre innere Schleife erzeugt viel Müll. Wenn Sie planen, Jedis + Redis zu benchmarken, müssen Sie den Overhead Ihres eigenen Programms niedrig halten.

  • Da Sie alles in die Hauptfunktion definiert haben, wird Ihre Schleife nicht vom JIT kompiliert (abhängig von der verwendeten JVM). Nur die inneren Methodenaufrufe dürfen sein. Wenn Sie möchten, dass das JIT effizient ist, sollten Sie Ihren Code in Methoden einbetten, die vom JIT kompiliert werden können.

  • Optional können Sie vor dem Ausführen der eigentlichen Messung eine Aufwärmphase hinzufügen, um zu vermeiden, dass der Aufwand für die Ausführung der ersten Iterationen mit dem Bare-Bone-Interpreter und die Kosten für das JIT selbst in Rechnung gestellt werden. p>

In Bezug auf Redis-Pipelining ist Ihre Pipeline jetzt viel zu lang. 100K Befehle in der Pipeline bedeutet, dass Jedis einen 6MB Puffer erstellen muss, bevor er etwas an Redis sendet. Das bedeutet, dass die Socket-Puffer (auf der Client-Seite und möglicherweise auf der Serverseite) gesättigt sind und dass Redis ebenfalls mit 6-MB-Kommunikationspuffern umgehen muss.

Außerdem ist Ihr Benchmark immer noch synchron (die Verwendung einer Pipeline macht es nicht magisch asynchron). Mit anderen Worten, Jedis beginnt erst mit dem Lesen der Antworten, wenn die letzte Abfrage Ihrer Pipeline an Redis gesendet wurde. Wenn die Pipeline zu lang ist, kann sie die Dinge blockieren.

Erwägen Sie, die Größe der Pipeline auf 100-1000 Vorgänge zu begrenzen. Natürlich werden dadurch mehr Roundtrips generiert, aber der Druck auf den Kommunikationsstapel wird auf ein akzeptables Niveau reduziert. Betrachten Sie zum Beispiel das folgende Programm:

%Vor%

Mit diesem Programm können Sie mit oder ohne Pipelining testen. Achten Sie darauf, die Anzahl der Iterationen (N-Parameter) zu erhöhen, wenn das Pipelining verwendet wird, sodass es für mindestens 10 Sekunden ausgeführt wird. Wenn Sie den Ausdruck in der Schleife auskommentieren, werden Sie feststellen, dass das Programm am Anfang langsam ist und schneller wird, wenn der JIT beginnt, die Dinge zu optimieren (deshalb sollte das Programm mindestens einige Sekunden laufen, um ein aussagekräftiges Ergebnis zu erhalten) / p>

Auf meiner Hardware (einer alten Athlon-Box) kann ich 8-9 Mal mehr Durchsatz erreichen, wenn die Pipeline benutzt wird. Das Programm könnte weiter verbessert werden, indem die Schlüssel / Wert-Formatierung in der inneren Schleife optimiert und eine Aufwärmphase hinzugefügt wird.

    
Didier Spezia 23.05.2013, 09:27
quelle

Tags und Links