Mon serveur Web VPS fonctionnant sur CentOS 5.4 (noyau Linux 2.6.16.33-xenU) de manière irrégulière (une fois par mois, à quelques semaines près) cesse de répondre en raison de la mise en route de OOM-Killer. Le contrôle du serveur montre que ce n'est pas le cas. normalement à court de mémoire, de temps en temps.
J'ai lu quelques blogs pointant vers cette page, qui traitent de la configuration du noyau pour mieux gérer les surcharges à l'aide des paramètres sysctl suivants:
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
D'après ce que je comprends (ce qui peut être faux, mais je ne trouve pas de définition canonique à clarifier), cela empêche le noyau de sur-allouer de la mémoire au-delà de l'échange + 80% de la mémoire physique.
Cependant, j'ai lu aussi quelques autres sources suggérant que ces paramètres ne sont pas une bonne idée - même si les critiques de cette approche semblent dire « ne pas faire les choses à briser votre système, plutôt que de tenter cette bidouille » dans l'hypothèse que la causalité est toujours connue.
Ma question est donc la suivante: quels sont les avantages et les inconvénients de cette approche dans le contexte d’un serveur Web Apache2 hébergeant environ 10 sites à faible trafic? Dans mon cas particulier, le serveur Web dispose de 512 Mo de RAM, avec 1024 Mo d’espace de permutation. Cela semble être suffisant pour la grande majorité du temps.
/proc/<PID>/oom_score_adj
à cette fin. Par exemple, si vous définissez oom_score_adj sur -1000 pour sshd, le tueur à mort ne ciblera jamais sshd lorsqu'il voudra tuer quelque chose. Arrêter complètement Kom Killer n’est pas une bonne idée car vos programmes ne seront plus capables de mémoire, et ils mourront de toute façon.La section 9.6 "Surcommission et MOO" dans la documentation mentionnée par @dunxd est particulièrement graphique sur les dangers de permettre une sur-utilisation. Cependant, cela
80
m’intéressait aussi et j’ai donc fait quelques tests.Ce que j'ai trouvé, c'est que cela
overcommit_ratio
affecte la RAM totale disponible pour TOUS les processus. Les processus racine ne semblent pas être traités différemment des processus utilisateur normaux.Fixer le ratio à
100
ou moins devrait fournir la sémantique classique pour laquelle les valeurs renvoyéesmalloc/sbrk
sont fiables. Définir des ratios inférieurs à ce qui100
pourrait être un moyen de réserver plus de RAM pour des activités non liées au processus telles que la mise en cache, etc.Donc, sur mon ordinateur avec 24 Go de RAM, avec permutation désactivée, 9 Go en cours d'utilisation, avec
top
affichageVoici quelques
overcommit_ratio
paramètres et la quantité de RAM que mon programme consommateur-ram peut prendre (en touchant chaque page) - dans chaque cas, le programme est sorti proprement une fois enmalloc
échec.En exécuter plusieurs à la fois, même si certains en sont l'utilisateur root, n'a pas modifié la quantité totale consommée ensemble. Il est intéressant de noter qu’il n’a pas été en mesure de consommer les 3 derniers GiB ou plus; le
free
n'a pas chuté beaucoup en dessous de ce qui est montré ici:Les expériences étaient désordonnées - tout ce qui utilise malloc au moment où toute la RAM est utilisée a tendance à planter, car de nombreux programmeurs ne savent pas comment vérifier les échecs de malloc en C, certaines bibliothèques de collections populaires l'ignorent entièrement, et C ++ et d'autres langages le sont également. pire.
La plupart des premières implémentations de RAM imaginaire que j'ai vues concernaient un cas très spécifique, dans lequel un seul processus volumineux - disons 51% + de mémoire disponible - était nécessaire pour pouvoir mettre
fork()
en placeexec()
un programme de support, généralement beaucoup plus petit. Les systèmes d'exploitation avec une sémantique de copie sur écriture le permettentfork()
, mais à condition que si le processus forké tente réellement de modifier trop de pages mémoire (chacune d'entre elles devrait ensuite être instanciée comme une nouvelle page indépendante du processus énorme initial) il finirait par se faire tuer. Le processus parent n'était en danger que si l'on allouait plus de mémoire et pouvait gérer l'épuisement des stocks, dans certains cas, il suffisait d'attendre un peu qu'un autre processus meure, puis de continuer. Le processus enfant vient généralement de se remplacer par un programme (généralement plus petit) viaexec()
et était alors libre de la condition.Le concept de surengagement de Linux est une approche extrême permettant à la fois
fork()
de se produire et de permettre à des processus uniques d’alléger massivement. Décès causés OOM-tueuses se produisent de manière asynchrone, même aux programmes qui font la poignée allocation de mémoire de façon responsable. Personnellement, je déteste la surcharge de travail à l’ échelle du système en général et celle de l’Oom-killer en particulier - elle favorise une approche diabolique de la gestion de la mémoire qui infecte les bibliothèques et, par leur intermédiaire, toutes les applications qui les utilisent.Je suggèrerais de fixer le rapport à 100 et d’avoir également une partition de swap qui ne serait généralement utilisée que par d’énormes processus - qui utilisent souvent une infime fraction de la partie de leur vie qui est bourrée dans le swap, et donc protéger la grande majorité des processus du mauvais fonctionnement du tueur OOM. Cela devrait garder votre serveur Web à l'abri d'une mort aléatoire, et s'il a été écrit pour le gérer de manière
malloc
responsable, même s'il ne risque pas de se tuer (mais ne pariez pas sur ce dernier).Cela signifie que je l'utilise dans
/etc/sysctl.d/10-no-overcommit.conf
la source