Comment définir les ajustements OOM Killer pour les démons en permanence?

12

En exécutant certains serveurs Linux avec un seul ou quelques démons de service système vitaux, je voudrais ajuster le tueur OOM pour ces processus démonisés au cas où quelque chose d'étrange se produirait. Par exemple, aujourd'hui un serveur Ubuntu faire fonctionner MySQL a un démon MySQL tué à cause des tonnes de apt-checkerprocessus ont été consommaient toute la mémoire et le noyau a pensé qu'il était une bonne idée de tuer MySQL.

Je sais que je peux ajuster le score en utilisant le /proc/$(pidof mysqld)/oom_score_adjfichier pour donner au noyau un indice que je ne préfère pas que MySQL soit tué, mais cela ne survit pas au redémarrage du service. Dois-je modifier les scripts init / upstart du package pour inclure ces ajustements? Je ne pense pas que ce soit une solution très élégante car je ferais des ajustements aux fichiers appartenant à un package. Serait-il possible de se connecter aux scripts upstart / init en général et de les ajuster conditionnellement? Ou suggéreriez-vous d'exécuter un script indéfini comme while true{ adjust_oom(); sleep 60;}?

gertvdijk
la source
Il est intéressant de noter qu'il est possible d'ajuster cela. Je suppose qu'il n'y a rien de mieux que votre boucle infinie pour accomplir le travail. L'OOM-killer est enfoui profondément dans le noyau et possède un algorithme très obscur.
Nils

Réponses:

8

Plusieurs systèmes modernes de supervision des démons ont un moyen de le faire. (En effet, puisqu'il existe un outil de chargement de chaîne pour le travail, ils ont sans doute tous un moyen de le faire.)

  • Upstart: utiliser oom scoredans le fichier de travail.
    score oom -500
  • systemd: utilisez le OOMScoreAdjust=paramètre de l'unité de service. Vous pouvez utiliser des fichiers de correctifs d'unité de service pour affecter les unités de service préemballées.
    [Service] 
    OOMScoreAdjust = -500
  • Famille daemontools : utilisez l'oom-kill-protectoutil du jeu d'outils nosh dans lerunprogramme du service.

    Si vous convertissez une unité de service système, l' convert-systemd-unitsoutil convertira en fait le OOMScoreAdjust=paramètre en une telle invocation de oom-kill-protect.

    #! / bin / nosh 

    oom-kill-protect - -500
    arguments du
    programme
    En bonus, vous pouvez le rendre paramétrable:
    oom-kill-protect - fromenv
    et définissez la valeur du paramètre dans l'environnement du service (présumé être lu à partir d'un envdir associé au service, ici manipulé avec la rcctlcale de l'ensemble d'outils Nosh):
    rcctl ensemble servicename oomprotect -500

Lectures complémentaires

  • Jonathan de Boyne Pollard (2016). oom-kill-protect. ensemble d'outils nosh. Logiciels.
  • James Hunt et Clint Byrum (2014). " oom score". Upstart Cookbook .
  • Lennart Poettering (2013-10-07). " OOMScoreAdjust". systemd.exec. pages de manuel de systemd. freedesktop.org.
  • Jonathan de Boyne Pollard. rcctl. ensemble d'outils nosh. Logiciels.
  • /unix//a/409454/5132
JdeBP
la source
9

Cela est possible dans Ubuntu en utilisant Upstart et l' oom scoreoption de configuration.

oom score

Linux a une fonction de suppression "Out of Memory". [...]

Normalement, le tueur OOM considère tous les processus de manière égale, cette strophe conseille au noyau de traiter ce travail différemment.

La valeur "d'ajustement" fournie à cette strophe peut être une valeur entière comprise entre -999 (très peu susceptible d'être tué par le tueur OOM) et 1000 (très susceptible d'être tué par le tueur OOM). [...]

Exemple:

# this application is a "resource hog"
oom score 1000

expect daemon
respawn
exec /usr/bin/leaky-app
gertvdijk
la source
Pour les lecteurs utilisant Ubuntu 16.04+, cela est devenu obsolète maintenant que Upstart a été remplacé par systemd.
gertvdijk
4

Vous pouvez le pirater dans MySQL lui-même (par exemple OpenSSH sshdfait cela), mais c'est un peu trop hardcore et très sale (problèmes avec les mises à jour, etc.)

Vous pouvez le faire dans un wrapper ou dans le script init - le score doit être hérité (et dans un wrapper que vous voudrez probablement faire de exec mysqld "$@"toute façon).

Utilisation cgroups- cela vous donnera un peu plus de flexibilité et il peut être rendu permanent dans le sens où les paramètres appropriés peuvent être appliqués automatiquement au redémarrage du service. Voir par exemple le contrôle de la priorité des applications à l'aide de cgroups pour plus d'informations. Pour atteindre l'automatisme que vous recherchez, vous voudrez probablement jeter un œil à libcgroup , qui contient un démon qui peut gérer à la volée la modification des cgroups d'un processus en cours selon un ensemble de règles, ou simplement utiliser le cgexecwrapper ( du même paquet).

peterph
la source