2016-01-27 10 views
5

L'installazionePuma o Unicorn VS Webbrick benchmark test di carico non mostra alcun miglioramento

Ok, io sono in esecuzione un'applicazione Rails su Heroku (tier gratuito).

ho 2 versioni delle applicazioni separate, consente di chiamare loro Staging e Fake-Production.

In Staging, sto usando Webbrick come server. Il mio Procfile è

web: rails s -p $PORT 

In Fake-Production, sto usando Puma come server. Il mio Procfile è

bundle exec puma -C config/puma.rb 

Ho configurato puma di correre con 2 operai e 1 filo per lavoratore. config/puma.rb è definito al di sotto (tratta da Heroku's Setting up Puma Webserver)

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 

mio database.yml è configurato per avere un pool di connessione di 20.

Il Test

Per fare il test di carico, ho usato lo strumento ApacheBench dal mio laptop per colpire un endpoint API. L'API fondamentalmente fa una query di database molto semplice per restituire una quantità fissa di record (non cambia).

mi ha colpito entrambe le implementazioni con il seguente codice:

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

I risultati

I risultati qui sono il più sorprendente. Mi aspettavo che l'implementazione di Puma eliminasse completamente l'implementazione di Webbrick, ma in realtà era quasi la stessa. Ho provato a colpire diversi endpoint API e diverse combinazioni di worker e thread Puma (a un certo punto, erano 4 worker e 5 thread) e tuttavia non c'erano miglioramenti visibili.

Webbrick Risultati

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) 

memoria Impact

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 Risultati (Più o meno lo stesso indipendentemente dal lavoratore/Il conteggio del filetto)

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) 

memoria Impact (4 lavoratori, 5 filetti)

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 

Sulla base dei frammenti di cui sopra, a volte il dispiegamento Puma sarà più veloce di Webbrick, mentre altre volte può essere più lento (come illustrato nello snippet) . Anche se è molto più veloce, la velocità non è significativa, probabilmente aumenterà solo di 1-5 richieste al secondo.

La mia domanda qui è, cosa sto sbagliando? Il mio pool di database è in qualche modo in errore? Sto analizzandolo in modo errato? Sto usando Puma erroneamente?

EDIT:

più alto carico CPU per Puma (5 lavoratore e 5 fili ciascuno)

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

maggior parte del tempo tuttavia, la sua sia 0,00 o inferiore a 0,1.

Per di più, l'unico codice che viene chiamato nel controllore è:

@package = Package.all 

Subito dopo, è seguito da rendering della risposta JSON che viene dichiarata in HAML.

Btw, Package.all restituisce solo circa 5 record.

EDIT 2:

UNICORNO RISULTATI

Implementato Unicorn in base alla. Esecuzione di 3 lavoratori di unicorno.

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) 

Una cosa Ive notato è che eseguono lo stesso codice di test di carico ab più volte torneranno diversi "Richieste per secondo". Questo vale sia per Unicorn che per Puma. Sia per Unicorn che per Puma, le migliori "Richieste per secondi" sono circa 48-50 mentre quelle peggiori sono circa 25-33.

In entrambi i casi, non ha ancora senso. Perché non sono Puma o Unicorno a schiacciare Webbrick?

+0

Ultimamente puma ha molti problemi con perdite di memoria e sono stato costretto a passare da server a phusion passeggero 5.023. Controlla il suo benchmark se questo ti aiuta. –

risposta

0

Confido che tu abbia seguito la guida di Heroku Deploying Rails Applications with the Puma Web Server accuratamente.

La mia ipotesi è che l'ambiente di test minimizzi i vantaggi del multi-threading, o il server HTTP sia imbullonato dal database SQL.

Le chiamate API, soprattutto se memorizzano nella cache i risultati del database, possono richiedere molto tempo. Avere 10 thread non è un vantaggio quando la CPU viene utilizzata al 100% solo 1. La gestione dei thread può effettivamente ostacolare le prestazioni in questo caso.

Il multi-threading è utile quando i thread di lavoro sono in attesa di molto tempo per risorse (database, file, ecc.), Invece di utilizzare la CPU.

La seconda possibilità è che il server HTTP sia vincolato dal database. È possibile che WEBrick si muova alla velocità consentita dal database, senza lasciare margini di miglioramento passando a un server HTTP con prestazioni migliori.

È necessario fornire una relazione di riferimento completa this.

Si noterà che Puma non è uno dei server HTTP Rails più veloci. Se tutto quello che ti interessa è la velocità, prova Unicorn o Torquebox 4 se si utilizza JRuby.

Ecco uno guide su come impostare Unicorn su Heroku.

+0

Ehi, grazie per la risposta. – Tikiboy

+0

Non penso che il mio processo sia legato alla CPU. Il valore più alto visto il carico della CPU è: source = web.1 dyno = heroku.123456789 sample # load_avg_1m = 2.98 La maggior parte delle volte tuttavia, è o 0,00 o inferiore a 0,1. Inoltre, l'unico codice richiamato nel controller è: @package = Package.all Immediatamente dopo, viene eseguito il rendering della risposta JSON dichiarata in HAML. Btw, Package.all restituisce solo circa 5 record. Proverò il tuo suggerimento su Unicorn e ispezionerò il link che hai fornito ulteriormente e ti ricontatteremo. Grazie! – Tikiboy

+0

Potrebbe benissimo essere quindi limitato dal database. Il tuo DB può servire solo il numero di richieste al secondo. Questo può limitare il tuo server web. Forse WEBrick si sta muovendo alla stessa velocità consentita dal database, senza lasciare margini di miglioramento. –