Question Combien de processus dois-je spécifier dans un WSGIDaemonProcess lors de l'exécution de Django via mod_wsgi?


Disons que j'ai 2 sites (Superuser et Serverfault) en cours d'exécution à partir de leur propre hôte virtuel Apache sur une boîte. Les deux sites sont alimentés par Django et fonctionnent sous Apache avec mod-wsgi. Un fichier de configuration typique pour l'un des sites ressemblera à ceci:

WSGIDaemonProcess serverfault.com user=www-data group=www-data processes=5

L'hôte est une machine Linux avec 4 Go de RAM sous Ubuntu. Quelqu'un peut-il suggérer le nombre de processus que je devrais spécifier ci-dessus pour mes 2 sites? Supposons qu'ils aient le même trafic que les sites Superuser et Serverfault réels.


20
2017-11-03 15:25


origine




Réponses:


Eh bien, combien de trafic faire les sites de super-utilisateur et Serverfault réels ont? Les hypothétiques ne sont pas d'une grande utilité s'ils n'ont pas assez d'informations pour faciliter la réponse ...

Le nombre de processus dans le cas le plus défavorable doit correspondre au nombre maximal de demandes par seconde que le site doit pouvoir gérer, divisé par le nombre de demandes par seconde qu'un processus peut gérer si toutes ces demandes sont exécutées selon votre action la plus lente. la réciproque du temps de traitement de cette action). Ajoutez le facteur de fudge que vous jugez approprié, en fonction de l'intervalle de confiance de vos mesures de req / s et de temps.

Le nombre de cas moyen est le même, mais vous divisez le nombre de requêtes / s par la moyenne pondérée de vos demandes par seconde pour chaque action (le poids correspond au pourcentage de demandes que vous attendez pour une action donnée). Encore une fois, les facteurs de fudge sont utiles.

La limite supérieure réelle du nombre de processus que vous pouvez exécuter sur la machine est dictée par la quantité de mémoire maximale que chaque processus prend. Déclenchez un processus, puis exécutez diverses actions gourmandes en mémoire (celles qui récupèrent et traitent un grand nombre de données, généralement) avec un jeu de données réaliste (si vous utilisez simplement un jeu de données jouet pour les tests, par exemple 50 ou 100). Si une de vos actions récupère et manipule chaque ligne du tableau, il ne sera pas utile de savoir quand ce tableau passera à 10 000 lignes) pour voir à quoi l'utilisation de la mémoire monte en flèche. Vous pouvez limiter artificiellement votre utilisation de la mémoire par processus avec un script qui renvoie les utilisateurs qui atteignent un certain seuil d'utilisation de la mémoire, au risque de provoquer des problèmes désagréables si vous définissez ce seuil trop bas.

Une fois que vous avez obtenu votre valeur d’utilisation de la mémoire, vous déduisez une certaine quantité de mémoire pour les frais généraux du système (j’aime bien 512 Mo), vous en déduisez davantage si d’autres processus s'exécutent sur le même ordinateur (une base de données, par exemple), puis un peu plus pour vous assurer de ne pas manquer de mémoire cache sur le disque (cela dépend de la taille de votre disque, mais là encore, je choisirais 512 Mo au minimum). C'est la quantité de mémoire que vous divisez par votre utilisation de mémoire par processus pour obtenir le plafond.

Si le nombre de processus dont vous avez besoin pour gérer votre charge de pointe est supérieur au nombre de processus que vous pouvez adapter à la boîte, vous avez besoin de davantage de machines (ou pour déplacer la base de données sur une autre machine, dans le cas le plus simple).

Vous y êtes, plusieurs années d’expérience dans le dimensionnement de sites Web distillés en un seul et petit message SF.


21
2017-11-03 15:44



Un autre facteur important pour le nombre de processus / threads est le temps que peut prendre une requête individuelle et sa répartition globale sur toutes les durées possibles. En d’autres termes, combien de demandes doivent être traitées à un moment donné et dont le temps de réponse est supérieur à la moyenne. Ce n’est donc pas aussi simple que des requêtes théoriques / s car l’impact de ces requêtes plus longues peut être considérable et dicter indûment les paramètres de configuration généraux. FWIW mod_wsgi 3.0 inclura une collection de statistiques intégrée pour essayer de capturer des données à ce sujet pour faciliter la configuration. - Graham Dumpleton
@Graham: relisez ma réponse, j'ai couvert cela en détail. Requests / sec est simplement l'inverse du temps de réponse, et il est plus facile de diviser par un nombre entier req / s que de le multiplier par un nombre décimal. - womble♦
Vous ne pouvez cependant pas vous concentrer uniquement sur le pire des cas, ni simplement sur la moyenne. Il doit être pondéré en fonction du pourcentage de demandes correspondant à des périodes, c'est-à-dire la répartition entre toutes les durées possibles. Si vous preniez vraiment votre pire temps de réponse, vous présenteriez des exigences irréalistes. Le problème, il est vraiment difficile de savoir quelle formule utiliser. C'est pourquoi, dans mod_wsgi 3.0, il y aura une collecte de statistiques intégrée qui examinera l'utilisation des threads et le pourcentage, en nombre et en durée, de l'utilisation d'un nombre de threads à la fois. - Graham Dumpleton
Le problème est peut-être que vous examinez les processus uniquement là où je suis inquiet de la manière dont les threads utilisent chaque facteur, ce qui n’est pas aussi simple. En d'autres termes, cette directive WSGIDaemonProcess indique 5 processus pour lesquels chaque processus utilise 15 threads par défaut. Autant que j'ai lu dans votre description, cela suppose des processus à un seul thread. Si ce n'est pas le cas, expliquez-moi comment votre modèle prend en charge les threads ainsi que les problèmes de contention / mise à l'échelle autour de GIL. Donc, qualifiez votre description de n'être valable que pour des processus à un seul thread et je ne discuterai pas. - Graham Dumpleton
L’approche "multithread-Apache + multiprocess-wsgi" n’est-elle pas la meilleure solution jusqu'à ce que vous soyez sûr à 99% que votre code Python et toutes ses dépendances sont thread-safe? - Tomasz Zieliński


femmeLa réponse est géniale, mais un peu difficile à comprendre et à appliquer pour les moins expérimentés. Je voudrais donner quelques chiffres empiriques et une comparaison d'applications "contenu simple" par rapport à "commerce électronique".

Il n'y a pas beaucoup de matière autour de la définition de différents cas d'utilisation en relation avec la configuration appropriée de mod_wsgi, donc j'espère que vous pourrez utiliser un peu de prose ici.

A) Sites et microsites CMS

Nous exploitons plusieurs sites Web clients, la plupart principalement des sites de contenu ou des micro-sites hébergeant le système de gestion de contenu django, des formulaires personnalisés et parfois du céleri pour des tâches en arrière-plan planifiées. Ces sites n’étaient pas avides de ressources, plusieurs d’entre eux s’exécutant en parallèle sur un seul processeur Intel Xeon 4 cœurs avec 32 Go de RAM. Voici la configuration que nous utilisons pour chacun de ces types de sites:

WSGIDaemonProcess example.com user=www-data processes=2 maximum-requests=100

Je parle d'environ 40 sites sur un seul serveur, la plupart d'entre eux avec leur site Staging en veille. Avec 2 processus (avec 15 threads chacun par défaut), les sites sont bien lotis, bien que leur capacité d'allocation de ressources de serveur soit limitée. La raison pour laquelle cette configuration est suffisante peut être justifiée par la nature simple de l’application (CMS): Aucune demande ne doit durer plus de deux millisecondes. Apache restera toujours détendu, de même que la charge du processeur.

B) Sites de commerce électronique

Nos sites les plus complexes sont caractérisés par des opérations locales encore peu coûteuses sur le plan informatique, mais des dépendances externes (par exemple, des services Web fournissant des données de réservation) coûteuses en temps de transaction. Les opérations avec des demandes externes occupent des threads beaucoup plus longtemps. Vous avez donc besoin de plus de threads pour prendre en charge le même nombre d'utilisateurs (par rapport à un simple site CMS par le haut). Pire encore, les threads sont parfois bloqués lorsqu'un service externe ne peut pas répondre à une demande immédiatement, parfois pendant quelques secondes. Cela peut entraîner des effets secondaires désagréables: les threads plaçant des requêtes vers le même service attendent jusqu'à ce que tous les threads mod_wsgi disponibles soient épuisés et bloqués en attente.

Pour ces scénarios, nous avons essayé d'utiliser 6 processus sans voir beaucoup de différence, et nous avons fini avec 12 Constatant une amélioration incomparable des performances et de la stabilité opérationnelle:

WSGIDaemonProcess example.com user=www-data processes=12 maximum-requests=100

Certains tests de charge simples avec 150 et 250 utilisateurs parallèles sont facilement gérés par le site en restant bien réactif (tout en 2 traite le site est inutilisable traiteur 50 utilisateurs en parallèle). Les 2 processeurs 6 processeurs Intel Xeon avec 32 Go de RAM fonctionnent bien en deçà de 25% d'utilisation du processeur, la consommation de RAM restant presque constante à moins de 25% également. Notez que nous utilisons ici une machine dédiée uniquement pour un seul site, nous ne volons donc pas les ressources dont d'autres sites pourraient avoir besoin.

Conclusion

L'utilisation d'un nombre plus élevé de processus est un compromis entre permettre à Apache d'utiliser ou non les ressources système disponibles. Si vous souhaitez conserver un système de serveur stable (pas un site Web!) Dans des conditions "d'attaque", conservez un nombre peu élevé. Si vous souhaitez qu'Apache vous aide à utiliser les ressources système (CPU, RAM) en cas de besoin, choisissez un nombre plus élevé. La hauteur à laquelle vous pouvez aller calcule un peu comme indiqué dans la réponse acceptée ci-dessus, et est finalement limitée par la puissance du processeur et la RAM disponibles.

(P.S .: Je garde le Section ConfigurationDirectives du wiki du projet modwsgi sous mon oreiller pour une lecture en arrière-plan de type Apache. Veillez également à comprendre et à surveiller votre Connexions ouvertes du serveur Apache.)


9
2017-11-14 03:57



Great post, mais pourquoi ne pas définir le nombre de threads? Puisque Python's GIL annule beaucoup des avantages des threads, je suppose que vous voudriez avoir plus de processus que de threads, mais y a-t-il un avantage à spécifier le nombre de threads? - Cerin
Le nombre par défaut de threads a 15 ans selon la documentation. Je ne pense pas qu'il y ait un avantage à spécifier cela explicitement. En fait, je me souviens de l'avoir laissé de côté pour une raison: il y avait un post sur SO ou une partie de la documentation qui recommandait d'omettre la valeur pour éviter les effets secondaires (je sais, ça a l'air bizarre). Malheureusement, je ne trouve pas cette source maintenant. Pour le reste de votre question (GIL), vous êtes probablement plus expert que moi, désolé. - Peterino
Merci pour cette configuration empirique. Cependant, gardez à l’esprit que, selon le ce post  You should never use maximum-requests in a production system unless you understand the implications and have a specific temporary need. - raratiru