web-dev-qa-db-fra.com

Impossible de modifier vm.max_map_count pour elasticsearch

Préhistoire

J'ai elasticsearch et SugarCRM7 fonctionnant sur CentOS 6.5. Chaque jour, je suis confronté au même problème: Java outOfMemory. Cela se produit en raison de la petite valeur vm.max_map_count, 65530 uniquement lorsque 262144 est recommandé.

Problème

Le problème est que vm.max_map_count semble immuable:

  1. Changement sous root

    Sudo sysctl -w vm.max_map_count=262144
    

    retour

    erreur: autorisation refusée sur la clé 'vm.max_map_count'

    Tandis que

    ps aux | grep Java
    

    Renvoie uniquement le processus grep

  2. Changer au démarrage d'Elasticsearch

    Sudo service elasticsearch start
    

    Renvoie également une erreur

    erreur: autorisation refusée sur la clé 'vm.max_map_count'

    Démarrage d'elasticsearch: [OK]

  3. Modifications manuelles via fichier (hack sale-sale):

    Sudo vi /proc/sys/vm/max_map_count
    

    Ne fonctionne pas non plus:

    "/ proc/sys/vm/max_map_count" [lecture seule] 1L, 6C

    - INSERER - W10: Avertissement: modification d'un fichier en lecture seule

    E45: L'option 'lecture seule' est définie (ajoutez! Pour remplacer)

    "/ proc/sys/vm/max_map_count" E212: impossible d'ouvrir le fichier pour l'écriture

    Tandis que

    ls -la /proc/sys/vm/ | grep max_map_count
    

    Retour

    -rw-r - r-- 1 racine root 0 10 avril 09:36 max_map_count

    (Mais je suppose que cela peut être normal pour Linux de parler du répertoire/proc)

Alors, comment puis-je changer la valeur de cette variable? Redémarrer elasticsearch tous les soirs n'est pas une bonne idée ... Ou peut-être que quelqu'un sait pourquoi cette erreur se produit?

14
Valentina

vous y êtes presque, peu importe qu'il s'agisse d'une machine virtuelle ou physique, ces paramètres sont toujours modifiables.

Je vais montrer 3 méthodes.

Quelques pré-informations:

1) Il est préférable d'exécuter en tant que root, si possible.

2) / proc sur unix n'est pas un vrai système de fichiers, c'est un système de fichiers noyau en mémoire, mais il semble être comme un système de fichiers disque normal. Vous pouvez l'appeler 'faux système de fichiers' ou 'système de fichiers spécial', vous ne pouvez pas éditer ces faux fichiers avec vi ou tout autre éditeur, car ce ne sont pas des fichiers, ils ressemblent simplement à des fichiers. Je suis resté avec le même problème il y a des années.

Mais il est simple de changer leurs valeurs, il suffit de recourir à un autre type de "mécanique" pour les modifier.

Je vais vous expliquer: Tout d'abord, vous devez être root: (Sudo fonctionne dans certaines distributions, mais pas sur d'autres distributions comme vous l'avez essayé, cette première méthode est universelle et fonctionne sur n'importe quel Linux, macOS ou Unix. J'espère que vous avez accès au mot de passe root.

Procédez à l'invite:

    $ su root

Saisissez le mot de passe root.

Maintenant que vous êtes root, vérifions la valeur actuelle de: / proc/sys/vm/max_map_count

    $ cat /proc/sys/vm/max_map_count  
    65536

Changeons-le:

    echo 262144 > /proc/sys/vm/max_map_count

Vérifions:

    cat /proc/sys/vm/max_map_count
    262144

C'est fait! Et c'est déjà appliqué et fonctionnel. En modifiant les valeurs de n'importe quel pseudo-fichier sous/proc, les paramètres deviennent instantanément actifs. Mais ils ne persistent pas après un redémarrage. Vous pouvez jouer avec les valeurs et mesurer les changements de performances dans elasticsearh ou dans toute autre mesure d'application ou de système. Allez régler votre système, écrivez les valeurs sur du papier, gardez les meilleures valeurs. En cas d'erreur, redémarrez et ils reviendront tous aux valeurs d'origine, et recommencent jusqu'à ce que toutes les valeurs souhaitées soient optimales. Il y a beaucoup de paramètres réglables sur le disque et la mémoire sous/proc. Et ils font une énorme différence et un gain de performances si vous les ajustez bien (et que vous en avez le temps). Tu es sur le bon chemin.

Une fois satisfait, rendons-les permanents:

Première méthode:

en utilisant / etc/rc.local

    vi /etc/rc.local 

placez tous les paramètres dans le fichier rc.local, par exemple:

    echo 220000000 > /proc/sys/vm/dirty_background_bytes
    echo 320000000 > /proc/sys/vm/dirty_bytes
    echo 0 > /proc/sys/vm/dirty_background_ratio
    echo 0 > /proc/sys/vm/dirty_ratio
    echo 500 > /proc/sys/vm/dirty_writeback_centisecs
    echo 4500 > /proc/sys/vm/dirty_expire_centisecs
    echo 1 > /proc/sys/net/ipv4/tcp_rfc1337
    echo 10 > /proc/sys/vm/swappiness
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag
    echo 120 > /proc/sys/net/ipv4/tcp_keepalive_time
    echo 0 > /proc/sys/vm/zone_reclaim_mode
    echo deadline > /sys/block/sda/queue/scheduler
    echo 8 > /sys/class/block/sda/queue/read_ahead_kb
    echo 1048575 > /proc/sys/vm/max_map_count

quitter l'éditeur vi en enregistrant le fichier.

Ces paramètres seront définis à chaque redémarrage, APRÈS le démarrage de tous les services d'initialisation, juste avant l'affichage de l'invite de connexion.

(/ etc/rc.local le fichier est exécuté après tous les services Linux de démarrage, il peut ne pas fonctionner si elasticsearch démarre avant lui en tant que service, mais cette méthode peut être utile sur une autre configuration si vous en avez besoin à l'avenir, ou vous pouvez utiliser comme ça en les mettant dans votre script d'initialisation elasticsearch, car le script d'initialisation s'exécute en tant que root, c'est donc la même syntaxe ci-dessus pour utiliser à l'intérieur des scripts d'initialisation)

Vous pouvez également les copier maintenant et les coller pour des changements instantanés. Les paramètres ci-dessus sont valides, réglés et fonctionnent sur mon serveur Apache cassandra. Si vous le souhaitez, essayez-les comme point de départ pour régler le vôtre.

Deuxième méthode pour les rendre permanents:

Les paramètres seront désormais définis AVANT tout service de démarrage sur Linux.

Modifier / etc/sysctl.conf, mettre les paramètres à l'intérieur

 vm.max_map_count=1048575
 vm.zone_reclaim_mode=0
 vm.dirty_background_bytes=220000000
 vm.dirty_background_ratio=0
 vm.dirty_bytes=320000000
 vm.dirty_ratio=0
 vm.swappiness=10

continuez avec les autres, enregistrez / etc/sysctl.conf, redémarrez votre serveur pour appliquer les modifications ou exécutez: sysctl -p pour appliquer les modifications sans redémarrer. Ils seront permanents à chaque redémarrage.

Les deux méthodes ci-dessus sont les plus courantes. Il y en a un autre, et cela peut fonctionner pour vous, c'est en utilisant Sudo, presque comme vous le faisiez:

au lieu de:

  Sudo sysctl -w vm.max_map_count=262144

essayer:

  echo 262144 | Sudo tee /proc/sys/vm/max_map_count

Cela fonctionne sur ubuntu.

Vérifier:

   user@naos:~$ cat /proc/sys/vm/max_map_count
   262144

J'espère que j'ai aidé d'une manière ou d'une autre, au moins en donnant les 3 options différentes pour résoudre le problème, car votre question a presque un an;)

Cordialement, Rafael Prado

13
user62739

Je pense que votre "machine virtuelle" est en fait un conteneur OpenVZ (que vous pouvez vérifier en exécutant virt-what).

Dans ce cas, vous ne pouvez pas modifier vm.max_map_count sysctl ou bien d'autres. Les valeurs sont fixes.

Il s'agit d'un problème bien connu avec elasticsearch ( problème # 4978 ). Ce n'est pas seulement Elasticsearch. Java sont bien connues pour mal fonctionner sur divers fournisseurs OpenVZ, principalement parce que les hôtes sont souvent mal réglés et que vous ne pouvez rien y faire. Un commentateur sur ce problème a fait écho à ce que serait ma recommandation exactement:

joshuajonah a commenté le 20 octobre 2015
C'est insensé. Je suppose que je vais passer à un KVM VPS.

4
Michael Hampton

Vous pouvez suivre les instructions officielles:

sysctl -w vm.max_map_count=262144

Pour rendre la modification permanente, mettez à jour le paramètre vm.max_map_count dans /etc/sysctl.conf

Voir https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html

0
heroin