Ist die Umgebung ohne Server mehr als 600 Mal langsamer? ~ Ich habe Benchmarking mit Go, Node.js und Python versucht! ~

Ist Serverless langsam?

Als ich Vorheriger Artikel schrieb, reagierte die von mir selbst erstellte Umgebung ohne Server nur langsam. Es gab ein Hautgefühl. Ich stellte mir vor, dass es langsamer als ein allgemeiner Server sein würde, da der Container intern mit Docker gestartet wurde. Aber um wie viel verschlechtert sich die Reaktionsgeschwindigkeit? Es gibt nicht viele vergleichende Artikel, deshalb habe ich beschlossen, sie tatsächlich zu messen.

Wie schnell ist AWS Lambda?

Ein kurzer Überblick über das technische Gebiet der serverlosen Architektur

Nach dem Artikel

Ist geschrieben. Dies bedeutet, dass in einer ähnlichen Umgebung ohne Server vorhergesagt werden kann, dass die Antwortzeit ungefähr gleich oder etwas langsamer sein wird.

Zu testende serverlose Umgebung

Wir verwenden eine lokale Umgebung ohne Server mit dem Namen Iron Functions. Diesbezüglich habe ich in der Vergangenheit einen Einführungsartikel geschrieben. Schauen Sie also bitte dort nach.

In 1 Stunde machen! Easy Home Serverlose Umgebung! -Einführung in die serverlose Anwendung zum ersten Mal-

Grob gesagt handelt es sich um ein praktisches Produkt, mit dem Sie problemlos eine Umgebung ohne Server wie AWS Lambda einführen können.

Benchmark

Diesmal wird für den Benchmark die Sprache Go, Node.js und Python verwendet. Schreiben Sie in jeder Sprache Code, der fast gleich funktioniert. Mal sehen, wie groß der Unterschied ist, wenn sie auf Serverless und auf HTTP-Servern ausgeführt werden, die für jede Sprache (Native) integriert sind.

Go Serverless

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Person struct {
	Name string
}

func main() {
	p := &Person{Name: "World"}
	json.NewDecoder(os.Stdin).Decode(p)
	fmt.Printf("Hello %v!", p.Name)
}

Go Native

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Person struct {
	Name string
}

func handler(w http.ResponseWriter, r *http.Request) {
	p := &Person{Name: "World"}
	json.NewDecoder(r.Body).Decode(p)
	fmt.Fprintf(w, "Hello %v!", p.Name)
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":2000", nil)
}

Node.js Serverless

name = "World";
fs = require('fs');
try {
	obj = JSON.parse(fs.readFileSync('/dev/stdin').toString())
	if (obj.name != "") {
		name = obj.name
	}
} catch(e) {}
console.log("Hello", name, "from Node!");

Node.js Native

const http = require('http');
name = "World";

http.createServer(
    (req, res) => {
         var body = "";
         req.on(
            "data",
            (chunk) => { body+=chunk; }
         );

         req.on(
            "end",
            () => {
                 obj = JSON.parse(body);
                 res.writeHead(200, {'Content-Type': 'text/plain'});
                 res.end('Hello ' + obj.name + " from Node Native!");
            }
         );

    }
).listen(6000);

Python Serverless

import sys
sys.path.append("packages")
import os
import json

name = "World"
if not os.isatty(sys.stdin.fileno()):
	obj = json.loads(sys.stdin.read())
	if obj["name"] != "":
		name = obj["name"]

print "Hello", name, "!!!"

Python Native

from http.server import BaseHTTPRequestHandler,HTTPServer
from json import loads
from io   import TextIOWrapper

class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers.get('content-length'))
        text  = TextIOWrapper(self.rfile).read(content_length)

        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()

        obj = loads(text)
        self.wfile.write("Hello {name} !! Welcome to Native Python World!!".format(name=obj["name"]).encode("utf-8"))

PORT = 1000
server =  HTTPServer(("127.0.0.1", PORT), Handler)

print("serving at port", PORT)
server.serve_forever()

Benching-Methode

Der Server für jeden Benchmark wird auf demselben Computer ausgeführt. Ubuntu 16.04 auf einer virtuellen Maschine mit 1 Kern und 2 GB Speicher. Der Server, der die Last stellt, und der Server, der die Last empfängt, sind identisch und verwenden Apache Bench. Bereiten Sie das folgende json und vor

johnny.json


{
    "name":"Johnny"
}

Das Laden erfolgt durch Auslösen der Nachbearbeitung mit Apache Bench. Die Anzahl der Anfragen beträgt 100 und die Anzahl der Parallelen beträgt 5. (Die Anzahl der Anfragen ist gering. Wird später beschrieben.) Zu diesem Zeitpunkt wird die Zeit bis zur Rückgabe der Antwort vom Server (Antwortzeit) gemessen.

#XXXX/XXXX ergänzt gegebenenfalls
ab -n 100 -c 5 -p johnny.json -T "Content-Type: application/json" http://localhost:XXXXX/XXXXX

Benchmark-Ergebnisse

Response Time min[ms] mean[ms] std[ms] median[ms] max[ms] Natives Verhältnis(mean)
Go Serverless 3951 6579 1010 6512 8692 1644.75
Go Native 0 4 5 2 37 -
Node Serverless 5335 14917 3147 15594 20542 621.54
Node Native 5 24 45 12 235 -
Python Serverless 5036 13455 4875 14214 29971 840.94
Python Native 6 16 4 16 26 -

** Bitte beachten Sie, dass die vertikale Achse der folgenden Abbildung eine logarithmische Skala ist (die Größenbeziehung wird zum leichteren Verständnis in Logarithmus ausgedrückt) **

image.png

Erwägung

Wie Sie der Tabelle entnehmen können, ist die Umgebung ohne Server mit ** Go mehr als 1600-mal langsamer als die native Umgebung. Sie können sehen, dass andere Node.js 600-mal langsamer und Python 800-mal langsamer ist. ** ** ** Wenn Sie die Ergebnisse von Python und Node.js vergleichen, finden Sie es möglicherweise seltsam, dass Python schneller ist. Wenn ich einen Folgetest in der nativen Umgebung versuchte, war Python manchmal schneller, wenn die Anzahl der Anforderungen gering und die Anzahl der Parallelen gering war. Wenn die Anzahl der Anforderungen 10.000 oder mehr beträgt, kann Node.js stabiler verarbeitet werden und die Verarbeitung wird schneller als bei Python abgeschlossen. Darüber hinaus führte die native Implementierung von Python manchmal zu einem Fehler und die Anforderung konnte nicht normal verarbeitet werden. Wahrscheinlich ist Go, das einen Geschwindigkeitsunterschied zu dieser Anzahl von Anforderungen aufweist, abnormal eingestellt. Hier möchte ich es mit dem oben erwähnten "AWS Lambda hat eine Verarbeitungszeit von 250 ms bis 8000 ms" vergleichen. Das Ergebnis dieser Benchmark war ein Ergebnis mit wenig persönlichem Unbehagen. Als ich mit Curl selbst eine Anfrage an Iron Functions gestellt habe, fühlte ich mich "langsam", und wenn ich für jede Anfrage einen Docker mache, denke ich, dass es keine Hilfe dafür gibt. Andererseits hatte ich den Eindruck, dass die 250 ms von AWS Lambda sehr schnell sind.

Tune Up AWS Lambda

Betrachtet man AWS Lambda, so scheint es zwei Arten von Startmethoden zu geben: Kaltstart und Warmstart. Ersteres unterscheidet sich nicht von dem intuitiven Serverless, und das Bild lautet, dass "für jede Anforderung ein Container erstellt wird", und letzteres scheint "ein einmal erstellter Container wird wiederverwendet". Auf diese Weise ist die Lambda-Implementierung schneller, da möglicherweise kein Container erstellt wird. Es scheint, dass. Ich denke, das ist der Grund, warum wir in 250 ms am schnellsten reagieren können. Auf der anderen Seite implementiert Iron Functions wahrscheinlich nur einen Kaltstart, also denke ich, dass es nicht so schnell ist. Wenn Go jedoch in einer von mir erstellten Umgebung ohne Server ausgeführt wird, ist Max von ca. 8600 ms meiner Meinung nach eine gute Verarbeitungsgeschwindigkeit. Natürlich gibt es einen Unterschied in der Anzahl der Kunden, die verarbeitet werden, aber ist die Geschwindigkeit der Containererstellung / -entsorgung nicht tatsächlich gleich? Ich dachte.

Ist der AWS Lambda Host eine gute Maschine?

Unten finden Sie einen Link zur Preisliste von AWS Lambda.

AWS Lambda Preisgestaltung https://aws.amazon.com/jp/lambda/pricing/

Der Preisplan scheint nach Nutzungsdauer * Speichernutzung berechnet zu werden, und es scheint, dass Sie die CPU nicht auswählen können. Wie ist die CPU zugeordnet? Es wurde in Hilfe geschrieben.

Und noch ein Artikel, der folgende Artikel

Die Geschichte der Produktionseinführung des Serverless Framework

Es wurde angegeben. Ich habe einige Umgebungstests ohne Server durchgeführt, aber die CPU-Auslastung des Host-Computers nimmt erheblich zu. Daher habe ich mich gefragt, wie die Host-Seite (Amazon) zahlen könnte, aber es scheint, dass der stündliche Stückpreis auf der Amazon-Seite hoch angesetzt ist. Außerdem wird Serverless grundsätzlich so ausgeführt, dass die Antwort erst zurückgegeben werden kann, nachdem der Container gestartet und verworfen wurde. Daher frage ich mich, ob die CPU für eine schnelle Antwort auf einen guten Wert eingestellt ist. Ich dachte.

Bankzusatz

Normalerweise beträgt die Anzahl der Benchmarks 10.000, oder ich denke, dass einige Muster ausgeführt werden. In diesem Experiment ist die Anzahl der Anforderungen jedoch auf ungefähr 100 begrenzt. Es gibt zwei Gründe. Eins ist, weil es "langsam" ist. Bei der Ausführung mit Serverless dauert es am schnellsten etwa 4000 ms. Daher haben wir keine großen Anfragen bewertet, da dies nicht realistisch war. Das zweite ist, weil es "instabil" ist. Eisenfunktionen haben ein instabiles Verhalten. Selbst wenn die Anforderung ungefähr 100 Mal ist, kann sie daher ungefähr 10 Mal fehlschlagen. Wenn Sie daher die Anzahl der Parallelen oder die Anzahl der Anforderungen erhöhen, besteht eine hohe Wahrscheinlichkeit, dass die Verarbeitung nicht möglich ist. Dies scheint auch vom Lebenszyklus des Doquer-Containers mit Eisenfunktionen abzuhängen, und es war ein Produkt, das eine Zeitüberschreitung aufwies oder keine Zeitüberschreitung aufwies, selbst wenn dieselbe Anfrage gesendet wurde, und es schwierig war, einen genauen Wert zu erhalten. Daher folgen die in diesem Artikel beschriebenen Daten dem Verarbeitungszeitwert selbst. Ich denke eher, dass es genauer ist zu erkennen, dass es im Vergleich zu Native eine Reihenfolge für die Verarbeitungszeit gibt. Auch die Tatsache, dass die Maschine, die die Last aufbringt, und die Maschine, die die Last empfängt, identisch sind, kann ein leicht ungenauer Benchmark sein. Dies liegt einfach daran, dass ich nicht zwei Umgebungen vorbereitet habe. Wenn Sie sich jedoch den Geschwindigkeitsunterschied zwischen der nativen Implementierung und der serverlosen Implementierung ansehen, ist es möglicherweise kein Problem, wenn Sie den Serverstatus beibehalten. .. Ich denke.

Impressionen

Dieser Benchmark hat sehr lange gedauert. Die Veröffentlichung wurde erheblich verzögert, da die Anforderung höchstens 600 Mal 3 bis 4 Stunden dauerte. Und die Langsamkeit von Serverless ist zu einem wirklich bemerkenswerten Ergebnis geworden. Lass es uns benutzen. Ich dachte, aber ich sollte es für eine Weile stoppen ... Andererseits ist AWS Lambda ausgezeichnet ... Und die Geschwindigkeit von Go's http-Server ist erstaunlich. Ich hätte nie gedacht, dass selbst eine so kleine Bank schnell sein würde. Außerdem ist Iron Functions schmerzhaft, da es fast kein japanisches Know-how gibt. Tatsächlich gibt es einen Reverse-Proxy namens fnlb, und eine Methode zum Clustering durch diesen wird ebenfalls offiziell vorbereitet. Dann ist es einfacher zu skalieren. Obwohl ich denke, dass der Vorgang an sich zu langsam ist, kann es wichtig sein, mehr zu tun oder den Engpass zu verbessern. Iron Functions selbst ist in erster Linie in Go geschrieben, also sollte es nicht so langsam sein, aber ... ich frage mich, ob es sich um den Docker-Container handelt ... Hmm. Es ist ein langer Weg ohne Server.

Recommended Posts

Ist die Umgebung ohne Server mehr als 600 Mal langsamer? ~ Ich habe Benchmarking mit Go, Node.js und Python versucht! ~
Ich habe Umgebungsvariablen in Docker festgelegt und in Python angezeigt.
Ich habe versucht, das Bild mit Python + OpenCV zu "glätten"
Ich habe versucht, das Bild mit Python + OpenCV zu "differenzieren"
Ich habe Jacobian und teilweise Differenzierung mit Python versucht
Ich habe Funktionssynthese und Curry mit Python versucht
Ich habe versucht, das Bild mit Python + OpenCV zu "binarisieren"
Ich habe versucht, mit Python Faiss zu laufen, Go, Rust
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, das Artikel-Update des Livedoor-Blogs mit Python und Selen zu automatisieren.
[New Corona] Ist der nächste Höhepunkt im Dezember? Ich habe die Trendanalyse mit Python versucht!
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit dplyr von R und pandas von Python zu vergleichen
Ich habe versucht, die API mit dem Python-Client von echonest zu erreichen
Ich habe die gleiche Datenanalyse mit kaggle notebook (python) und PowerBI gleichzeitig versucht ②
Ich habe die gleiche Datenanalyse mit kaggle notebook (python) und PowerBI gleichzeitig versucht ①
Ich habe auch versucht, die Funktionsmonade und die Zustandsmonade mit dem Generator in Python nachzuahmen
Ich habe versucht, das Offline-Spracherkennungssystem Julius mit Python in der virtuellen Docker-Umgebung auszuführen
Ich habe versucht, das Bild mit Python + OpenCV "gammakorrektur" zu machen
Ich habe versucht, die Python-Bibliothek von Ruby mit PyCall zu verwenden
Ich habe versucht, Follow Management mit Twitter API und Python (einfach)
Ich habe versucht, den Chi-Quadrat-Test in Python und Java zu programmieren.
Ich habe versucht, die Unterschiede zwischen Java und Python aufzuzählen
Ich habe versucht, die Benutzeroberfläche neben Python und Tkinter dreiäugig zu gestalten
Ich habe fp-Wachstum mit Python versucht
Ich habe versucht, mit Python zu kratzen
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Ich habe zum ersten Mal versucht, mit DynamoDB und Step Functions eine serverlose Stapelverarbeitung zu erstellen
Der neueste NGINX ist ein Anwendungsserver! ?? Ich habe den Benchmark von NGINX Unit mit PHP, Python, Go! !!
Ich habe die Geschwindigkeit von Hash mit Topaz, Ruby und Python verglichen
Ich habe versucht, das Ranking des Qiita-Adventskalenders mit Python zu kratzen
Ich habe versucht, die Anfängerausgabe des Ameisenbuchs mit Python zu lösen
Ich habe versucht, mit Selenium und Python einen regelmäßigen Ausführungsprozess durchzuführen
Ich habe versucht herauszufinden, ob ReDoS mit Python möglich ist
Ich habe versucht, Gesichtsmarkierungen mit Python und Dlib leicht zu erkennen
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe es mit Grumpy versucht (Python ausführen).
Ich mochte den Tweet mit Python. ..
Ich habe mit PyQt5 und Python3 gespielt
Ich habe versucht, die statistischen Daten der neuen Corona mit Python abzurufen und zu analysieren: Daten der Johns Hopkins University
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, E-Mails von Node.js und Python mithilfe des E-Mail-Zustelldienstes (SendGrid) von IBM Cloud zuzustellen!
[Python] Ich habe versucht, die Nacht der Galaxienbahn mit WordCloud zu visualisieren!
Ich versuchte, Trauer und Freude über das Problem der stabilen Ehe auszudrücken.
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe versucht, den Winkel von Sin und Cos mit Chainer zu lernen
Ich habe es mit den Top 100 PyPI-Paketen versucht.> Ich habe versucht, die auf Python installierten Pakete grafisch darzustellen
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
Ich habe versucht, die Standardrolle neuer Mitarbeiter mit Python zu optimieren
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe versucht, eine Mac Python-Entwicklungsumgebung mit pythonz + direnv zu erstellen
Ich habe die Geschwindigkeit der Listeneinschlussnotation für und während mit Python2.7 gemessen.
Ich habe versucht, den Google-Kalender mit CSV-Terminen mithilfe von Python und Google API zu aktualisieren