Nombre optimal de processus par licorne par CPU

16

Nous exécutons une application Web Ruby on Rails sous Unicorn. Notre application n'est pas strictement liée au processeur (nous avons un système double Xeon E5645 avec 12 cœurs et une valeur moyenne de charge maximale est d'environ 6). Nous avons commencé avec 40 employés Unicorn au départ, mais l'empreinte mémoire de l'application a augmenté au fil du temps. Donc, maintenant, nous devons réduire le nombre de processus de travail. Je pensais que la formule standard (nombre de cœurs CPU + 1) s'applique également à Unicorn mais mon collègue a essayé de me convaincre que nous devrions réserver plus d'instances Unicorn par CPU et a fourni ce lien . Pourtant, je ne sais pas exactement pourquoi devons-nous consacrer autant de mémoire aux processus inactifs de la Licorne.

Ma question est: quelle est la raison d'avoir plus d'une instance Unicorn par cœur de processeur? Est-ce dû à une particularité architecturale de la Licorne? Je suis conscient que les processus Unicorn occupés ne peuvent pas accepter de nouvelles connexions (nous utilisons des sockets de domaine UNIX pour communiquer avec les instances Unicorn BTW), mais je pensais que le backlog avait été introduit exactement pour résoudre ce problème. Est-il possible de surmonter ces 2 à 8 instances Unicorn par règle CPU de toute façon?

Alex
la source

Réponses:

17

D'accord, j'ai enfin trouvé la réponse. Le nombre optimal de travailleurs Unicorn n'est pas directement connecté au nombre de cœurs de processeur, cela dépend de votre charge et de la structure / réactivité de l'application interne. Fondamentalement, nous utilisons le profileur d'échantillonnage pour déterminer l'état des travailleurs, nous essayons de garder les travailleurs à 70% inactifs et 30% à faire le travail réel. Ainsi, 70% des échantillons devraient "attendre l'appel de select () pour obtenir une demande du serveur frontal". Notre recherche a montré qu'il n'y a que 3 états effectifs de travailleurs: 0 à 30% des échantillons sont inactifs, 30 à 50% des échantillons sont inactifs et 50 à 70% des échantillons sont inactifs (oui, nous pouvons obtenir plus d'échantillons inactifs mais là ne sert à rien car la réactivité des applications ne change pas de manière significative). Nous considérons une situation de 0 à 30% comme une "zone rouge" et une situation de 30 à 50% une "zone jaune".

Alex
la source
1
Pouvez-vous expliquer comment vous échantillonnez l'état de ces travailleurs?
dps
6

Vous avez raison sur N + 1 pour les travaux liés au processeur.

D'un autre côté, la licorne n'utilise pas de threads, donc chaque IO op. bloque le processus et un autre processus peut lancer et analyser les en-têtes HTTP, concaténer les chaînes et effectuer toutes les tâches gourmandes en processeur dont il a besoin pour servir l'utilisateur (en le faisant plus tôt pour réduire la latence des demandes).

Et vous voudrez peut-être avoir plus de threads / processus que de cœurs. Imaginez la situation suivante: req. A prend dix fois plus que req. B, vous avez plusieurs demandes A simultanées et la demande B rapide est simplement mise en file d'attente en attendant la fin de A-req. Donc, si vous pouvez prédire le nombre de demandes lourdes, vous pouvez utiliser ce nombre comme une autre directive pour régler le système.

darkk
la source
1
Bon point, supposons que les demandes sont réparties plus ou moins également et sont assez légères (nous avons en fait des demandes lourdes mais elles sont gérées par un autre pool de licornes). Si toutes les demandes deviennent soudainement lourdes (par exemple en cas de famine d'E / S sur un nœud de base de données), nous serons en panne quel que soit le nombre d'instances par CPU, je suppose. Eh bien, probablement la meilleure façon de connaître la vérité est d'effectuer une sorte de test de charge.
Alex
Oui, les tests vous le diront. Ou, si vous avez déjà commencé, vous pouvez grep les journaux et rechercher le nombre maximum de demandes simultanées. Je suis sûr que vous enregistrez à la fois le temps de demande et le temps de réponse du backend. Nginx sera votre ami si vous ne le faites pas. :)
darkk