2017-12-05 6 views
1

First off, hat jemand einen Leistungsvergleich für Durchsatz/Latenz zwischen einer GRPC Client-Server-Implementierung v/s eine websocket + protobuf Client-Server-Implementierung getan? Oder zumindest etwas Ähnliches.GRPC Server-Antwort-Latenz

Um dieses Ziel zu erreichen, probiere ich das Beispiel JAVA helloworld Grpc Client-Server aus und versuche die Latenz der Antwort mit einem ähnlichen Websocket Client-Server zu vergleichen. Momentan probiere ich dies sowohl mit Client als auch mit Server auf meinem lokalen Rechner aus.

Der Websocket Client-Server hat eine einfache While-Schleife auf der Serverseite. Für den Grpc-Server bemerke ich, dass er ein asynchrones Ausführungsmodell verwendet. Ich vermute, dass es für jede Clientanforderung einen neuen Thread erstellt, was zu zusätzlichen Verarbeitungsgemeinkosten führt. Die Latenzzeit der Web-Socket-Antwort, die ich z. B. gemessen habe, liegt in der Größenordnung von 6-7 ms, und das Beispiel von grpc zeigt eine Latenzzeit von etwa 600-700 ms, was dem Protobuf-Overhead Rechnung trägt.

Um einen ähnlichen Vergleich für grpc zu tun, ist es eine Möglichkeit, die grpc Server synchron zu laufen? Ich möchte in der Lage sein, den Overhead der Thread-Erstellung/-Versendung und anderer solcher interner Kosten, die durch die asynchrone Behandlung eingeführt werden, zu eliminieren.

Ich verstehe, dass es eine protobuf Overhead in grpc beteiligt ist, die nicht da in meinem websocket Client-Server-Beispiel. Dies kann ich jedoch durch die Messung des durch die Protobuf-Verarbeitung eingeführten Overheads erklären.

Auch wenn ich die grpc Server synchron ausgeführt werden kann, kann ich messen mindestens den Faden Dispatch/Asynchron-Overhead-Verarbeitungs?

Ich bin relativ neu zu JAVA, so entschuldigen Sie meine Ignoranz.

Antwort

1

Benchmarking in Java ist leicht falsch zu verstehen. Sie müssen viele Sekunden aufwärmen, um mehrere JIT-Levels zu aktivieren. Außerdem benötigen Sie Zeit, um die Heap-Größe auszugleichen. In einem vereinfachten One-Shot-Benchmark ist es aufgrund des Ladens von Klassen leicht zu sehen, dass der Code, der zuletzt ausgeführt wird, am schnellsten ist (unabhängig davon, was dieser Code ist). 600 ms ist eine wahnsinnig große Zahl für die gRPC-Latenz; Wir sehen around 300 µs median latency in Google Compute Engine zwischen zwei Computern mit TLS. Ich erwarte, dass Sie keine Warm-ups haben, also zählen Sie die Zeit, die Java benötigt, um gRPC zu laden und Java mit seinem Interpreter mit gRPC zu messen.

Es gibt keine synchrone Version des gRPC Servers, und selbst wenn es noch ist, würde mit einem separaten Thread standardmäßig ausgeführt. grpc-java verwendet einen Cache-Thread-Pool, so dass gRPC nach einer anfänglichen Anfrage in der Lage sein sollte, einen Thread zum Aufrufen des Service erneut zu verwenden.

Die Kosten zwischen Threads Springen ist im Allgemeinen gering, obwohl es tail Latenz hinzufügen. In einigen prozessinternen NOOP-Benchmarks sehen wir die RPC-Fertigstellung in 8 μs mit den zusätzlichen Threads und 4 μs ohne. Wenn Sie wirklich wollen, können Sie serverBuilder.directExecutor() verwenden, um den Threadsprung zu vermeiden. Beachten Sie, dass die meisten Dienste langsamer mit dieser Option erhalten und eine wirklich schlechte Tail-Latenz haben, da die Dienstverarbeitung E/A verzögern kann.

0

Um einen ähnlichen Vergleich für grpc zu machen, gibt es eine Möglichkeit, den Grpc-Server synchron zu betreiben? Ich möchte in der Lage sein, den Overhead der Thread-Erstellung/-Versendung und anderer solcher interner Kosten, die durch die asynchrone Behandlung eingeführt werden, zu eliminieren.

Sie können einen synchronen Client erstellen. Im Allgemeinen ist das asynchrone Verfahren viel schneller. (Getestet in Scala) Sie können einfach alle Ressourcen verwenden, die Sie nicht blockierend erhalten haben. Ich würde einen Test darüber erstellen, wie viele Anfragen von wie vielen Clients der Server pro Sekunde verarbeiten kann.Sie können die eingehende Anfrage pro Client begrenzen, um sicherzustellen, dass Ihr Service nicht abstürzt. Asynchron ist auch besser für HTTP 2. HTTP 2 bietet Multiplexing.

Für eine Benchmark kann ich Metrics empfehlen. Sie können die Messwerte über den Protokoll- oder HTTP-Endpunkt verfügbar machen.