Rappel des épisodes précédents : le benchmark avec ab donne 3400 req/s en fournissant les images dans la réponse, et seulement 2800 req/s avec la redirection 302, avec 21Mo de RAM utilisée.
En utilisant le serveur gunicorn (simplement en mettant server="gunicorn", workers=5 dans l'appel à bottle.run()) on monte à 14000 req/s, la machine ayant 4 cœurs, augmenter le nombre de workers au delà de 5 ne fait absolument rien gagner. Mais là on est à 30Mo de RAM pour le master, et 21Mo de RAM pour chacun des 5 workers. Rapide mais on le paye !
J'ai tenté de mettre l'application bottle derrière apache et le mod_wsgi (processes=5 threads=2), on est à 12000 req/s, les processus mod_wsgi font 23Mo de RAM chacun, on est quasiment à la vitesse et aux ressources de gunicorn mais avec le reste des possibilités d'apache, si on en a besoin.
Et puis j'ai poussé un petit peu, tester les différents serveurs disponibles comme backend de bottle, il y en a plein.
Et je suis tombé sur bjoern, qui utilise la libev, bibliothèque C de gestion d'évènements, très - très - rapide.
On monte à 17000 req/s, en monothread et 20Mo de RAM.
C'est assez bluffant par rapport à toutes les autres solutions, surtout par rapport aux 3400 du serveur par défaut !
Mais bon, en fait, pourquoi pas lancer l'application bjoern 5 fois et utiliser un load-balancer devant ?
lighttpd fait ça très bien et on est à 13000 req/s, honorable, mais sans intérêt.
Alors on va utiliser un vrai load-balancer : haproxy !
Et donc 5 backend appli standalone avec bjoern, un haproxy en round-robin devant, on passe à 19500 req/s !
On a le même score avec 4 backend, la machine a 4 cœurs, fait tourner haproxy et aussi l'outil de benchmark, on sature sans surcharger le nombre de backend.
Si on descends à 2 backend, on monte à 19700 req/s, à 3 backend on est à 19800 req/s.
On s'y attends un peu : 5 processus qui bossent (3 backends bottle/bjoern, haproxy, et ab pour les tests) sur 4 cœurs c'est en général ce qui optimise le plus, mais c'est assez marginal.
Bien sûr, là on est à 3*20Mo+8Mo = 68Mo.
En bref haproxy ça déchire, on le savait déjà, on le constate encore, 8Mo de RSS, c'est tout mini.
Et le serveur WSGI bjoern est très impressionnant dans l'écosystème WSGI.
Et on descends pas en dessous de 20Mo de RAM pour un processus Python.
Et le Bottle.redirect() est plus lent, avec 3*bjoern+haproxy on est à 15000 req/s, c'est naze.
Conclusion, fournir le fichier directement et ne pas faire de redirection 302 (de toute façon, derrière, côté navigateur, on fait deux requêtes, c'est atroce), utiliser bjoern en server WSGI, et si on vaut load-balancer entre plusieurs serveurs, dégainer haproxy.
Yth.
Pour info le /etc/haproxy/haproxy.cfg utilisé est le suivant (les timeout servent pas dans notre cas, mais haproxy geint si on les met pas) :
[^] # Re: En Python (Flask)
Posté par Yth (Mastodon) . En réponse au journal Le taptempo du web. Évalué à 6.
Alors pour faire suite à mon commentaire originel que vous trouverez avec le code python en Bottle ici :
https://linuxfr.org/users/spacefox/journaux/java-presque-9-000-requetes-par-seconde-avec-8-mo-de-ram#comment-1893297
Rappel des épisodes précédents : le benchmark avec ab donne 3400 req/s en fournissant les images dans la réponse, et seulement 2800 req/s avec la redirection 302, avec 21Mo de RAM utilisée.
En utilisant le serveur gunicorn (simplement en mettant
server="gunicorn", workers=5dans l'appel àbottle.run()) on monte à 14000 req/s, la machine ayant 4 cœurs, augmenter le nombre de workers au delà de 5 ne fait absolument rien gagner. Mais là on est à 30Mo de RAM pour le master, et 21Mo de RAM pour chacun des 5 workers. Rapide mais on le paye !J'ai tenté de mettre l'application bottle derrière apache et le mod_wsgi (processes=5 threads=2), on est à 12000 req/s, les processus mod_wsgi font 23Mo de RAM chacun, on est quasiment à la vitesse et aux ressources de gunicorn mais avec le reste des possibilités d'apache, si on en a besoin.
Et puis j'ai poussé un petit peu, tester les différents serveurs disponibles comme backend de bottle, il y en a plein.
Et je suis tombé sur bjoern, qui utilise la libev, bibliothèque C de gestion d'évènements, très - très - rapide.
On monte à 17000 req/s, en monothread et 20Mo de RAM.
C'est assez bluffant par rapport à toutes les autres solutions, surtout par rapport aux 3400 du serveur par défaut !
Mais bon, en fait, pourquoi pas lancer l'application bjoern 5 fois et utiliser un load-balancer devant ?
lighttpd fait ça très bien et on est à 13000 req/s, honorable, mais sans intérêt.
Alors on va utiliser un vrai load-balancer : haproxy !
Et donc 5 backend appli standalone avec bjoern, un haproxy en round-robin devant, on passe à 19500 req/s !
On a le même score avec 4 backend, la machine a 4 cœurs, fait tourner haproxy et aussi l'outil de benchmark, on sature sans surcharger le nombre de backend.
Si on descends à 2 backend, on monte à 19700 req/s, à 3 backend on est à 19800 req/s.
On s'y attends un peu : 5 processus qui bossent (3 backends bottle/bjoern, haproxy, et ab pour les tests) sur 4 cœurs c'est en général ce qui optimise le plus, mais c'est assez marginal.
Bien sûr, là on est à 3*20Mo+8Mo = 68Mo.
En bref haproxy ça déchire, on le savait déjà, on le constate encore, 8Mo de RSS, c'est tout mini.
Et le serveur WSGI bjoern est très impressionnant dans l'écosystème WSGI.
Et on descends pas en dessous de 20Mo de RAM pour un processus Python.
Et le Bottle.redirect() est plus lent, avec 3*bjoern+haproxy on est à 15000 req/s, c'est naze.
Conclusion, fournir le fichier directement et ne pas faire de redirection 302 (de toute façon, derrière, côté navigateur, on fait deux requêtes, c'est atroce), utiliser bjoern en server WSGI, et si on vaut load-balancer entre plusieurs serveurs, dégainer haproxy.
Pour info le /etc/haproxy/haproxy.cfg utilisé est le suivant (les timeout servent pas dans notre cas, mais haproxy geint si on les met pas) :
Et le code final bottle, avec exactement deux dépendances python : bottle et bjoern