Question redis bgsave a échoué car fork Impossible d'allouer de la mémoire


tout: voici ma mémoire de serveur avec 'free -m'

              total       used       free     shared    buffers     cached
 Mem:         64433       49259      15174          0          3         31
 -/+ buffers/cache:      49224      15209
 Swap:         8197        184       8012

mon redis-server a utilisé la mémoire 46G, il reste presque 15G de mémoire libre

Comme je le sais, fork est une copie en écriture, il ne devrait pas échouer quand il y a 15G de mémoire disponible, ce qui est suffisant pour les structures de noyau nécessaires.

de plus, quand redis-server utilisait de la mémoire 42G, bgsave est ok et fork est ok aussi.

Existe-t-il un paramètre vm que je peux régler pour que le retour de fourchette réussisse?

Merci.


29
2017-08-01 04:24


origine


Réponses:


De proc (5) pages de manuel:

/ proc / sys / vm / overcommit_memory

Ce fichier contient le mode de comptabilisation de la mémoire virtuelle du noyau. Les valeurs sont:

0: surconsommation heuristique (c'est la valeur par défaut)

1: toujours surcharger, ne jamais vérifier

2: toujours vérifier, jamais trop

En mode 0, les appels de mmap (2) avec MAP_NORESERVE définis ne sont pas vérifiés et la vérification par défaut est très faible, ce qui entraîne le risque de voir le processus "OOM tué". Sous Linux 2.4   toute valeur non nulle implique le mode 1. En mode 2 (disponible depuis Linux 2.6), l'espace d'adressage virtuel total sur le système est limité à (SS + RAM * (r / 100)), où SS est la taille   de l'espace de swap, et RAM est la taille de la mémoire physique, et r est le contenu du fichier / proc / sys / vm / overcommit_ratio.


17
2017-08-01 05:02



Plus précisément, du Redis FAQ

Le schéma de sauvegarde en arrière-plan de Redis repose sur la sémantique de fork dans les systèmes d’exploitation modernes: redis forks (crée un processus enfant) qui est une copie exacte du parent. Le processus enfant vide la base de données sur le disque et quitte finalement. En théorie, l'enfant devrait utiliser autant de mémoire que le parent étant une copie, mais en réalité, grâce à la sémantique de la copie sur écriture mise en œuvre par la plupart des systèmes d'exploitation modernes, le processus parent et enfant partagera les pages de mémoire communes. Une page sera dupliquée uniquement lorsqu'elle change dans l'enfant ou dans le parent. Puisque, en théorie, toutes les pages peuvent changer pendant que le processus enfant enregistre, Linux ne peut pas indiquer à l'avance la quantité de mémoire que l'enfant va prendre. Par conséquent, si le paramètre oversommit_memory est défini sur zéro, il échouera Il est nécessaire de dupliquer toutes les pages de la mémoire parente, de sorte que si vous disposez d’un ensemble de données Redis de 3 Go et de seulement 2 Go de mémoire libre, cela échouera.

Régler oversommit_memory à 1 indique que Linux se détend et exécute le fork de manière plus optimiste, et c'est bien ce que vous voulez pour Redis.

Redis ne nécessite pas autant de mémoire que le système d’exploitation pense qu’il peut écrire sur le disque.


56
2018-04-23 21:11



Modifier /etc/sysctl.conf et ajouter:

vm.overcommit_memory=1

Puis redémarrez sysctl avec:

Sur FreeBSD:

sudo /etc/rc.d/sysctl reload

Sous Linux:

sudo sysctl -p /etc/sysctl.conf

37
2018-06-08 00:03