Rails 4: ralentissements inattendus dans le rendu de la vue et ActiveRecord

Je développe des applications sur Rails et j’ai des problèmes de performances. Ci-dessous, j’ai décrit et fourni toutes les technologies, configurations et méthodes que j’ai utilisées. J’ai essayé plusieurs méthodes pour résoudre ce problème mais rien n’a aidé. Ceci est également décrit ci-dessous. Quelqu’un peut-il voir quel est le problème? Je vous remercie!

Le problème

Ouvrez le site plusieurs fois et consultez le journal:
INFO -- : Completed 200 OK in 171ms (Views: 149.3ms | ActiveRecord: 7.3ms)
INFO -- : Completed 200 OK in 217ms (Views: 183.7ms | ActiveRecord: 8.9ms)
INFO -- : Completed 200 OK in 221ms (Views: 188.2ms | ActiveRecord: 11.7ms)
INFO -- : Completed 200 OK in 165ms (Views: 143.3ms | ActiveRecord: 7.1ms)
Bien.

Maintenant, générons la charge avec wrk -t10 -c10 -d10s http://example.com et revoyons le journal:
INFO -- : Completed 200 OK in 178ms (Views: 157.6ms | ActiveRecord: 8.1ms)
INFO -- : Completed 200 OK in 270ms (Views: 241.6ms | ActiveRecord: 8.8ms)
INFO -- : Completed 200 OK in 505ms (Views: 460.7ms | ActiveRecord: 12.0ms)
INFO -- : Completed 200 OK in 501ms (Views: 350.8ms | ActiveRecord: 136.0ms)
INFO -- : Completed 200 OK in 777ms (Views: 468.1ms | ActiveRecord: 269.1ms)
INFO -- : Completed 200 OK in 936ms (Views: 624.7ms | ActiveRecord: 285.1ms)
...
INFO -- : Completed 200 OK in 881ms (Views: 617.4ms | ActiveRecord: 251.6ms)
...
INFO -- : Completed 200 OK in 3289ms (Views: 2614.2ms | ActiveRecord: 326.4ms)
INFO -- : Completed 200 OK in 3369ms (Views: 2624.0ms | ActiveRecord: 409.4ms)
INFO -- : Completed 200 OK in 3203ms (Views: 2369.2ms | ActiveRecord: 382.1ms)
...
INFO -- : Completed 200 OK in 431ms (Views: 281.1ms | ActiveRecord: 126.3ms)
...
Quels sont ces terribles ralentissements?

 wrk -t10 -c10 -d10s http://example.com Running 10s test @ http://example.com 10 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.26s 96.38ms 1.39s 75.00% Req/Sec 0.00 0.00 0.00 100.00% 36 requests in 10.09s, 0.97MB read Socket errors: connect 0, read 0, write 0, timeout 32 Requests/sec: 3.57 Transfer/sec: 98.62KB 

Des rails

J’utilise la dernière version de Rails – 4.2.4.
sortie de bundle list – github gist
application.rb – github gist
production.rb – github gist
database.yml – github gist

J’utilise Actifs_Aparanoid pour tous mes modèles. ( WHERE deleted_at IS NULL )

Toutes les requêtes N + 1 sont éliminées (analysées manuellement et avec une puce ).
Toutes les tables sont InnoDB et ont beaucoup d’indices. 99% des tables ont 50 lignes ou moins, le rest 1% – 200 ou moins. C’est très peu de données.

La page Je fais référence à environ 30-35 requêtes SQL et environ 30 partiels.
Requêtes utilisant …
– COUNT – 0
– GROUP BY – 1
– COMMANDE PAR – 10
– LIMIT – 10
– JOIN – 1 (rejoint une table)
– Utilisation des fonctions MAX, MIN, CONCAT et autres – NON

Mes modèles sont écrits en Slim .

Configuration du serveur

CPU – Processeur Intel un kernel Sandy Bridge
RAM – 1GM
Type de disque – SSD

Système opérateur

Ubuntu 14.04 LTS 64bit

Echangez 1 Go. Paramètres d’échange optimisés:
cat /proc/sys/vm/swappiness => 10
cat /proc/sys/vm/vfs_cache_pressure => 50

Base de données

MySQL 5.5. Essayé d’optimiser avec mysqltuner et tuning-primer.
Configuration actuelle: github gist

Dernier rapport mysqltuner: perl mysqltuner.pl --buffers --dbstat --outputfile result_mysqltuner.txt github gist

Dernier rapport de mise au point: ./tuning-primer.sh github gist

J’ai des avis de l’avertissement Temporary tables created on disk . C’est parce que j’ai des colonnes TEXT dans MySQL. Googling J’ai trouvé que monter un répertoire temporaire MySQL en mémoire est une bonne idée. Je l’ai donc fait: tmpdir /var/mysqltmp . J’ai suivi ce guide .

mytop output :

  Queries: 37.4k qps: 0 Slow: 1.9k Se/In/Up/De(%): 91/00/00/00 Sorts: 0 qps now: 1 Slow qps: 0.0 Threads: 4 ( 1/ 2) 00/00/00/00 Cache Hits: 29.0k Hits/s: 0.4 Hits now: 0.0 Ratio: 85.5% Ratio now: 0.0% Key Efficiency: 99.4% Bps in/out: 75.8/ 1.9k Now in/out: 22.6/ 2.1k Id User Host/IP DB Time Cmd State Query -- ---- ------- -- ---- --- ----- ---------- 1444 root localhost site 73737 Sleep 2337 root localhost site 658 Sleep 2340 root localhost site 322 Sleep 2342 root localhost 0 Query show full processlist 

Interprète de rbuy

Rbenv: rbenv -v => rbenv 0.4.0-154-g9e664b5
Ruby: ruby -v => ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]

Mon ruby ​​est compilé avec jemalloc (meilleure allocation de mémoire):
RbConfig::CONFIG['LIBS'] => "-lpthread -ljemalloc -ldl -lcrypt -lm "
J’ai suivi ce guide .

J’ai essayé les deux rbuy avec une allocation de mémoire par défaut et personnalisée. Ruby avec jemalloc semble être plus rapide.

serveur Web

nginx -v => nginx version: nginx/1.8.0
Nginx.conf actuel (simplifié): github gist
Site nginx actuel conf (simplifié): github gist

Serveur d’application

J’ai essayé les deux passagers et Puma. Mais sans résultat.

Phusion Passager

passenger -v => Phusion Passenger version 5.0.18
Configuration: github gist

Puma

bundle exec puma -v => puma version 2.13.4
J’ai également essayé le serveur Puma dans les deux modèles de cluster (1 worker) et de thread.
Voici la dernière config pour Puma en mode thread: github gist