Est-ce que quelqu’un d’autre constate le même problème ? C’est un forum de taille et de trafic assez modestes. Il y a quatre processus de travail pitchfork, et il semble que l’un d’entre eux traite la grande majorité des requêtes entrantes et utilise plus de mémoire que les autres. Il y a beaucoup d’espace d’échange (swap) utilisé, et en relançant délibérément pitchfork, cela diminue considérablement. J’en conclus donc que les processus pitchfork ont actuellement beaucoup de pages froides actuellement échangées vers le swap.
Cela se produit après 20 jours de fonctionnement, sur une machine équipée de 4 Go de RAM et de 4 Go de swap.
Il ne serait pas bon de se retrouver à court de swap. Il ne serait pas non plus bon de voir tout cet espace d’échange être réintégré en mémoire, ce qui pourrait se produire lorsque pitchfork effectuera finalement une collecte des ordures (garbage collect).
Est-ce que quelqu’un d’autre observe quelque chose de similaire ? N’hésitez pas à partager la configuration de votre machine !
La sortie de vmstat indique qu’il n’y a actuellement aucune pression sur la mémoire - aucune activité de pagination. Ma préoccupation est qu’il y a un danger, et non que mon installation fonctionne mal actuellement.
Pour finir sur une note plus sérieuse, celui qui fait tout le travail n’a que 100 Mo de RSS de plus que la moyenne ? Ça me semble normal, ou est-ce que je rate quelque chose ?
J’aimerais voir les statistiques d’un forum plus actif. Il semble que le nombre cumulé de requêtes soit important, et le mien est loin d’être très sollicité.
Oui, les différences de RSS sont relativement modestes, mais passer de 300 Mo à 500 Mo représente tout de même une différence significative en proportion.
Plus frappant est l’utilisation du swap. Avant le recyclage, j’observe :
# free
total used free shared buff/cache available
Mem: 3904968 1888140 77308 679004 1939520 1147220
Swap: 4194288 1226344 2967944
et après :
# free
total used free shared buff/cache available
Mem: 3904968 1486412 1422380 640744 996176 1587908
Swap: 4194288 309892 3884396
À mon avis, le recyclage a libéré environ 1,3 Go (différence entre la mémoire utilisée et le swap).
Je ne pense pas avoir vu autant de swap nécessaire en utilisant unicorn : d’où le titre.
Comme je l’ai dit, je serais intéressé de voir les chiffres d’autres instances.
Il est normal qu’un seul processus pitchfork supporte la majeure partie de la charge — les autres ne sont sollicités que lorsque le premier est occupé. Il est également normal que la mémoire augmente avec le temps. Bien qu’elle devrait finir par atteindre un état stable, une fois que tout est « réchauffé », comme les caches et le JIT Ruby.
Voici un graphique issu de l’un de nos clusters de production, sur une période de 7 jours. Il suit le processus ayant la plus forte consommation mémoire. Les lignes vertes en pointillés indiquent les déploiements (c’est-à-dire les redémarrages complets de pitchfork) :
On peut donc voir qu’il augmente après le démarrage initial, mais se stabilise ensuite juste en dessous de 1,4 Go. Ce cluster sert des centaines de sites, donc la comparaison en termes de chiffres n’est peut-être pas la plus pertinente… mais j’espère que la visualisation de la croissance est utile.
Regarder les valeurs RSS par processus ne donne pas toute l’histoire. Pitchfork est un « serveur web à fourchette » (forking web server). Il démarre donc le processus « moule » (mold), puis tous les travailleurs (workers) sont créés par fourchetage (fork) à partir de celui-ci, avec un modèle mémoire en écriture-copie (copy-on-write). Ainsi, bien que le RSS puisse afficher 500 Mo pour worker[0], environ 200 Mo de cette quantité sont partagés avec le moule et tous les autres travailleurs.
Dans un avenir proche, nous espérons pouvoir activer la fonctionnalité de « reforking » de Pitchfork. Elle tue périodiquement les travailleurs et les recrée par fourchetage à partir d’un travailleur déjà réchauffé, afin qu’ils partagent le maximum de mémoire possible au fil du temps. Il faudra toutefois effectuer certains travaux pour s’assurer que tout notre code est compatible avec ce type de modèle
Belle visualisation, merci. Je ne dirais pas que c’est stabilisé, mais le taux de croissance n’est plus aussi élevé qu’avant.
Le reforking périodique semble être une excellente chose à introduire — si c’est possible, merci de le signaler ici une fois que ce sera en place.
Pouvez-vous en dire quelque chose sur les lignes vertes ? Je suis intéressé par le moment (s’il y en a un) où les pitchforks effectuent une collecte des ordures, ce qui la provoque et quel est son effet pendant qu’elle est en cours.
Les lignes vertes correspondent aux déploiements de mises à jour. En gros : ./launcher rebuild app.
Ruby (et JS, que nous exécutons au sein des processus Ruby via MiniRacer/v8) effectue une collecte des ordures en continu pendant son exécution, et en réponse aux signaux du système d’exploitation. Je ne pense donc pas qu’il y ait un grand avantage à faire quoi que ce soit manuellement.
Merci. Je serais curieux de voir comment les choses évoluent à long terme, ce qui ne sera pas évident sur un serveur mis à jour relativement souvent. Dans mon cas, j’ai attendu 20 jours, puis j’ai choisi de relancer le serveur à l’aide de pitchfork, ce qui m’a donné certaines indications, mais qui a également remis le compteur à zéro.