2016-01-27 11 views
5

Das SetupPuma oder Unicorn VS Webbrick Belastungstest Benchmark zeigt keine Verbesserung

Ok, ich bin eine Rails-Anwendung auf Heroku (freie Schicht) ausgeführt wird.

I 2 separate Anwendungs-Releases haben, lässt sie Staging nennen und Fälschungs-Production.

In Staging, verwende ich Webbrick als Server. Mein Procfile ist

web: rails s -p $PORT 

In Fälschungs-Production, ich bin mit Puma als Server. My Procfile ist

bundle exec puma -C config/puma.rb 

I PUMA konfiguriert haben mit 2 Arbeiter und 1 Faden pro Arbeiter auszuführen. config/puma.rb ist unten (aus Heroku's Setting up Puma Webserver) definiert

workers Integer(ENV['WEB_CONCURRENCY'] || 2) 
threads_count = Integer(ENV['MAX_THREADS'] || 1) 
threads threads_count, threads_count 

preload_app! 

rackup  DefaultRackup 
port  ENV['PORT']  || 3000 
environment ENV['RACK_ENV'] || 'development' 

on_worker_boot do 
    # Worker specific setup for Rails 4.1+ 
    # See: https://devcenter.heroku.com/articles/deploying-rails-applications- with-the-puma-web-server#on-worker-boot 
    ActiveRecord::Base.establish_connection 
end 

Mein database.yml konfiguriert ist, einen Verbindungspool von 20

Das Test

zu haben, um die Lasttests zu tun, ich benutze ApacheBench-Tool von meinem Laptop, um einen API-Endpunkt zu treffen. Die API führt grundsätzlich eine sehr einfache Datenbankabfrage durch, um eine feste Anzahl von Datensätzen zurückzugeben (ändert sich nicht).

traf ich beide Einsätze mit dem folgenden Code:

ab -n 1000 -c 100 https://<some heroku endpoint>?access_token=f73f50514c 

Die Ergebnisse

Die Ergebnisse hier sind die meisten überraschend. Ich hatte erwartet, dass der Puma-Einsatz den Webbrick-Einsatz komplett zunichte machen würde, aber in Wirklichkeit war es fast dasselbe. Ich habe versucht, verschiedene API-Endpunkte sowie verschiedene Kombinationen von Puma-Arbeitern und -Threads zu treffen (an einem Punkt waren es 4 Arbeiter und 5 Fäden) und doch gab es keine sichtbaren Verbesserungen.

Webbrick Ergebnisse

Server Software:  WEBrick/1.3.1 
Server Hostname:  webbrick-build.herokuapp.com 
Server Port:   443 
SSL/TLS Protocol:  TLSv1,DHE-RSA-AES128-SHA,2048,128 

Document Path:   /api/v1/packages?access_token=f73f50514c6 
Document Length:  488 bytes 

Concurrency Level:  100 
Time taken for tests: 21.484 seconds 
Complete requests:  1000 
Failed requests:  0 
Total transferred:  995000 bytes 
HTML transferred:  488000 bytes 
Requests per second: 46.55 [#/sec] (mean) 
Time per request:  2148.360 [ms] (mean) 
Time per request:  21.484 [ms] (mean, across all concurrent requests) 
Transfer rate:   45.23 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  714 1242 278.1 1214 2012 
Processing: 248 842 493.6 699 2883 
Waiting:  247 809 492.3 677 2876 
Total:  1072 2085 643.5 1929 4845 

Percentage of the requests served within a certain time (ms) 
    50% 1929 
    66% 2039 
    75% 2109 
    80% 2168 
    90% 2622 
    95% 3821 
    98% 4473 
    99% 4646 
100% 4845 (longest request) 

Speicher Schlag

source=web.1 dyno=heroku.1234567899 sample#memory_total=198.41MB sample#memory_rss=197.60MB sample#memory_cache=0.30MB sample#memory_swap=0.51MB sample#memory_pgpgin=103879pages sample#memory_pgpgout=53216pages 

Puma Ergebnisse (mehr oder weniger die gleiche, unabhängig von Arbeiter/Gewindezählimpuls)

Server Software:  Cowboy 
Server Hostname:  puma-build.herokuapp.com 
Server Port:   443 
SSL/TLS Protocol:  TLSv1,DHE-RSA-AES128-SHA,2048,128 

Document Path:   /api/v1/packages?access_token=fb7168c147adc2ccd83b2 
Document Length:  489 bytes 

Concurrency Level:  100 
Time taken for tests: 23.299 seconds 
Complete requests:  1000 
Failed requests:  0 
Total transferred:  943000 bytes 
HTML transferred:  489000 bytes 
Requests per second: 42.92 [#/sec] (mean) 
Time per request:  2329.949 [ms] (mean) 
Time per request:  23.299 [ms] (mean, across all concurrent requests) 
Transfer rate:   39.52 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  743 1304 283.9 1287 2092 
Processing: 253 951 740.3 684 5353 
Waiting:  253 898 729.0 627 5196 
Total:  1198 2255 888.0 1995 7426 

Percentage of the requests served within a certain time (ms) 
    50% 1995 
    66% 2085 
    75% 2213 
    80% 2444 
    90% 3755 
    95% 4238 
    98% 5119 
    99% 5437 
100% 7426 (longest request) 

Speicher Impact (4 Arbeiter, 5 Fäden)

source=web.1 dyno=heroku.1234567890 sample#memory_total=406.75MB sample#memory_rss=406.74MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=151515pages sample#memory_pgpgout=47388pages 

Basierend auf dem Schnipsel oben, manchmal die Puma-Bereitstellung als Webbrick schneller sein, während andere Male es langsamer sein können (wie im Snippet gezeigt) . Auch wenn es viel schneller ist, ist die Geschwindigkeit nicht signifikant, wahrscheinlich nur um 1-5 Anfragen/Sek.

Meine Frage hier ist, was mache ich falsch? Ist mein Datenbankpool irgendwie fehlerhaft? Prüfe ich ihn falsch? Benutze ich Puma falsch?

EDIT:

höchste CPU Last für Puma (5 Arbeiter und 5 jeweils Gewinde)

source=web.1 dyno=heroku.123456789 sample#load_avg_1m=2.98 

Die meiste Zeit jedoch seine entweder 0,00 oder kleiner als 0,1 ist.

Hinzu kommt, dass der einzige Code, der in der Steuerung aufgerufen wird, ist:

@package = Package.all 

Unmittelbar danach wird gefolgt von der JSON-Antwort-Rendering, die in HAML deklariert wird.

Btw, Package.all gibt nur ca. 5 Datensätze zurück.

EDIT 2:

EINHORN ERGEBNISSE

Implementiert Unicorn nach. Running 3 Einhorn Arbeiter.

Server Software:  Cowboy 
Server Hostname:  unicorn-build.herokuapp.com 
Server Port:   443 
SSL/TLS Protocol:  TLSv1,DHE-RSA-AES128-SHA,2048,128 

Document Path:   /api/v1/packages?access_token=f73f50514c6b8a3ea 
Document Length:  488 bytes 

Concurrency Level:  100 
Time taken for tests: 22.311 seconds 
Complete requests:  1000 
Failed requests:  0 
Total transferred:  942000 bytes 
HTML transferred:  488000 bytes 
Requests per second: 44.82 [#/sec] (mean) 
Time per request:  2231.135 [ms] (mean) 
Time per request:  22.311 [ms] (mean, across all concurrent requests) 
Transfer rate:   41.23 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  846 1326 294.5 1304 2720 
Processing: 245 627 342.8 540 3061 
Waiting:  244 532 313.6 470 3057 
Total:  1232 1954 463.0 1874 4875 

Percentage of the requests served within a certain time (ms) 
    50% 1874 
    66% 2016 
    75% 2161 
    80% 2250 
    90% 2466 
    95% 2799 
    98% 3137 
    99% 3901 
100% 4875 (longest request) 

Eine Sache, ich habe bemerkt, ist, dass das gleiche ab Lasttestcode ausgeführt wird mehrmals verschiedene „Requests pro Sekunde“ zurück. Dies gilt sowohl für Unicorn als auch für Puma. Sowohl für Unicorn als auch für Puma liegen die besten "Anfragen pro Sekunde" bei 48-50, während die schlimmsten bei 25-33 liegen.

Wie auch immer, es macht immer noch keinen Sinn. Warum zerquetschen weder Puma noch Unicorn Webbrick?

+0

In letzter Zeit hat Puma viele Probleme mit Speicherlecks und ich war gezwungen, Server auf Phusion Passagier 5.023 zu wechseln. Überprüfen Sie die Benchmark, wenn das hilft. –

Antwort

0

Ich vertraue darauf, dass Sie die Anleitung von Heroku Deploying Rails Applications with the Puma Web Server gründlich gelesen haben.

Meine Vermutung ist, dass Ihre Testumgebung Multi-Threading Vorteile minimiert, oder der HTTP-Server ist von der SQL-Datenbank Flaschenhals.

Ihre API-Aufrufe können, besonders wenn sie Datenbankergebnisse zwischenspeichern, CPU-intensiv sein. 10 Threads zu haben ist kein Vorteil, wenn die CPU zu 100% nur von 1 benutzt wird. Das Verwalten der Threads kann in diesem Fall die Performance beeinträchtigen.

Multithreading ist nützlich, wenn Ihre Worker-Threads lange auf Ressourcen (Datenbanken, Dateien usw.) warten, anstatt die CPU zu verwenden.

Die zweite Möglichkeit ist, dass Ihr HTTP-Server durch die Datenbank eingeschränkt ist. Es kann sein, dass sich WEBrick so schnell bewegt, wie es die Datenbank zulässt, und dadurch keinen Platz für Verbesserungen lässt, indem auf einen leistungsfähigeren HTTP-Server umgeschaltet wird.

Sie sollten this umfassenden Benchmark-Bericht lesen.

Sie werden feststellen, dass Puma nicht einer der schnellsten Rails HTTP-Server ist. Wenn Sie nur auf die Geschwindigkeit achten, versuchen Sie Unicorn, oder Torquebox 4, wenn Sie JRuby verwenden.

Hier ist ein guide zum Einrichten von Unicorn auf Heroku.

+0

Hey, danke für die Antwort. – Tikiboy

+0

Ich glaube nicht, dass mein Prozess CPU-gebunden ist. Die höchste CPU-Auslastung ist: source = web.1 dyno = heroku.123456789 Beispiel # load_avg_1m = 2.98 Die meiste Zeit jedoch ist es entweder 0,00 oder kleiner als 0,1. Darüber hinaus ist der einzige Code, der in der Steuerung aufgerufen wird: @package = Package.all Unmittelbar danach folgt das Rendern der JSON-Antwort, die in HAML deklariert wird. Btw, Package.all gibt nur ungefähr 5 Datensätze zurück. Ich werde Ihren Vorschlag auf Unicorn versuchen und überprüfen Sie den Link, den Sie weiter gegeben und dann zurück zu Ihnen. Danke! – Tikiboy

+0

Es könnte sehr gut Datenbank sein dann eingeschränkt. Ihre Datenbank kann nur so viele Anfragen pro Sekunde verarbeiten. Dies kann Ihren Webserver einschränken. Vielleicht bewegt sich WEBrick so schnell, wie es die Datenbank zulässt, und lässt keinen Raum für Verbesserungen. –