Rsync a déclenché le tueur de MOO Linux sur un seul fichier de 50 Go

66

J'ai un seul fichier de 50 Go sur server_A et je le copie sur server_B. je cours

server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file

Server_B dispose de 32 Go de RAM avec 2 Go d’échange. Il est principalement inactif et aurait dû disposer de beaucoup de RAM libre. Il y a beaucoup d'espace disque. À environ 32 Go, le transfert est interrompu car le côté distant a fermé la connexion.

Server_B a maintenant quitté le réseau. Nous demandons au centre de données de le redémarrer. Quand je regarde le journal du noyau d'avant son crash, je vois qu'il utilisait 0 octet de swap et que la liste de processus utilisait très peu de mémoire (le processus rsync était répertorié comme utilisant 600 Ko de RAM), mais oom_killer était sauvage, et la dernière chose dans le journal est l'endroit où il tue le processus de lecture du noyau de metalog.

Il s’agit du noyau 3.2.59, 32 bits (aucun processus ne peut donc mapper plus de 4 Go).

C'est presque comme si Linux donnait plus de priorité à la mise en cache qu'aux démons en cours d'exécution de longue durée. Ce qui donne?? Et comment puis-je empêcher que cela ne se reproduise?

Voici le résultat de oom_killer:

Sep 23 02:04:16 [kernel] [1772321.850644] clamd invoked oom-killer: gfp_mask=0x84d0, order=0, oom_adj=0, oom_score_adj=0
Sep 23 02:04:16 [kernel] [1772321.850649] Pid: 21832, comm: clamd Tainted: G         C   3.2.59 #21
Sep 23 02:04:16 [kernel] [1772321.850651] Call Trace:
Sep 23 02:04:16 [kernel] [1772321.850659]  [<c01739ac>] ? dump_header+0x4d/0x160
Sep 23 02:04:16 [kernel] [1772321.850662]  [<c0173bf3>] ? oom_kill_process+0x2e/0x20e
Sep 23 02:04:16 [kernel] [1772321.850665]  [<c0173ff8>] ? out_of_memory+0x225/0x283
Sep 23 02:04:16 [kernel] [1772321.850668]  [<c0176438>] ? __alloc_pages_nodemask+0x446/0x4f4
Sep 23 02:04:16 [kernel] [1772321.850672]  [<c0126525>] ? pte_alloc_one+0x14/0x2f
Sep 23 02:04:16 [kernel] [1772321.850675]  [<c0185578>] ? __pte_alloc+0x16/0xc0
Sep 23 02:04:16 [kernel] [1772321.850678]  [<c0189e74>] ? vma_merge+0x18d/0x1cc
Sep 23 02:04:16 [kernel] [1772321.850681]  [<c01856fa>] ? handle_mm_fault+0xd8/0x15d
Sep 23 02:04:16 [kernel] [1772321.850685]  [<c012305a>] ? do_page_fault+0x20e/0x361
Sep 23 02:04:16 [kernel] [1772321.850688]  [<c018a9c4>] ? sys_mmap_pgoff+0xa2/0xc9
Sep 23 02:04:16 [kernel] [1772321.850690]  [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850694]  [<c08ba7e6>] ? error_code+0x5a/0x60
Sep 23 02:04:16 [kernel] [1772321.850697]  [<c08b0000>] ? cpuid4_cache_lookup_regs+0x372/0x3b2
Sep 23 02:04:16 [kernel] [1772321.850700]  [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850701] Mem-Info:
Sep 23 02:04:16 [kernel] [1772321.850703] DMA per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850704] CPU    0: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850706] CPU    1: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850707] CPU    2: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850709] CPU    3: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850711] CPU    4: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850713] CPU    5: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850714] CPU    6: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850716] CPU    7: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850718] Normal per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850719] CPU    0: hi:  186, btch:  31 usd:  70
Sep 23 02:04:16 [kernel] [1772321.850721] CPU    1: hi:  186, btch:  31 usd: 116
Sep 23 02:04:16 [kernel] [1772321.850723] CPU    2: hi:  186, btch:  31 usd: 131
Sep 23 02:04:16 [kernel] [1772321.850724] CPU    3: hi:  186, btch:  31 usd:  76
Sep 23 02:04:16 [kernel] [1772321.850726] CPU    4: hi:  186, btch:  31 usd:  29
Sep 23 02:04:16 [kernel] [1772321.850728] CPU    5: hi:  186, btch:  31 usd:  61
Sep 23 02:04:16 [kernel] [1772321.850731] CPU    7: hi:  186, btch:  31 usd:  17
Sep 23 02:04:16 [kernel] [1772321.850733] HighMem per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850734] CPU    0: hi:  186, btch:  31 usd:   2
Sep 23 02:04:16 [kernel] [1772321.850736] CPU    1: hi:  186, btch:  31 usd:  69
Sep 23 02:04:16 [kernel] [1772321.850738] CPU    2: hi:  186, btch:  31 usd:  25
Sep 23 02:04:16 [kernel] [1772321.850739] CPU    3: hi:  186, btch:  31 usd:  27
Sep 23 02:04:16 [kernel] [1772321.850741] CPU    4: hi:  186, btch:  31 usd:   7
Sep 23 02:04:16 [kernel] [1772321.850743] CPU    5: hi:  186, btch:  31 usd: 188
Sep 23 02:04:16 [kernel] [1772321.850744] CPU    6: hi:  186, btch:  31 usd:  25
Sep 23 02:04:16 [kernel] [1772321.850746] CPU    7: hi:  186, btch:  31 usd: 158
Sep 23 02:04:16 [kernel] [1772321.850750] active_anon:117913 inactive_anon:9942 isolated_anon:0
Sep 23 02:04:16 [kernel] [1772321.850751]  active_file:106466 inactive_file:7784521 isolated_file:0
Sep 23 02:04:16 [kernel] [1772321.850752]  unevictable:40 dirty:0 writeback:61 unstable:0
Sep 23 02:04:16 [kernel] [1772321.850753]  free:143494 slab_reclaimable:128312 slab_unreclaimable:4089
Sep 23 02:04:16 [kernel] [1772321.850754]  mapped:6706 shmem:308 pagetables:915 bounce:0
Sep 23 02:04:16 [kernel] [1772321.850759] DMA free:3624kB min:140kB low:172kB high:208kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolate
d(file):0kB present:15808kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:240kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tm
p:0kB pages_scanned:0 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850763] lowmem_reserve[]: 0 869 32487 32487
Sep 23 02:04:16 [kernel] [1772321.850770] Normal free:8056kB min:8048kB low:10060kB high:12072kB active_anon:0kB inactive_anon:0kB active_file:248kB inactive_file:388kB unevictable:0kB isolated(anon)
:0kB isolated(file):0kB present:890008kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:513008kB slab_unreclaimable:16356kB kernel_stack:1888kB pagetables:3660kB unstable:0
kB bounce:0kB writeback_tmp:0kB pages_scanned:1015 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850774] lowmem_reserve[]: 0 0 252949 252949
Sep 23 02:04:16 [kernel] [1772321.850785] lowmem_reserve[]: 0 0 0 0
Sep 23 02:04:16 [kernel] [1772321.850788] DMA: 0*4kB 7*8kB 3*16kB 6*32kB 4*64kB 6*128kB 5*256kB 2*512kB 0*1024kB 0*2048kB 0*4096kB = 3624kB
Sep 23 02:04:16 [kernel] [1772321.850795] Normal: 830*4kB 80*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 8056kB
Sep 23 02:04:16 [kernel] [1772321.850802] HighMem: 13*4kB 14*8kB 2*16kB 2*32kB 0*64kB 0*128kB 2*256kB 2*512kB 3*1024kB 0*2048kB 136*4096kB = 561924kB
Sep 23 02:04:16 [kernel] [1772321.850809] 7891360 total pagecache pages
Sep 23 02:04:16 [kernel] [1772321.850811] 0 pages in swap cache
Sep 23 02:04:16 [kernel] [1772321.850812] Swap cache stats: add 0, delete 0, find 0/0
Sep 23 02:04:16 [kernel] [1772321.850814] Free swap  = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.850815] Total swap = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.949081] 8650736 pages RAM
Sep 23 02:04:16 [kernel] [1772321.949084] 8422402 pages HighMem
Sep 23 02:04:16 [kernel] [1772321.949085] 349626 pages reserved
Sep 23 02:04:16 [kernel] [1772321.949086] 7885006 pages shared
Sep 23 02:04:16 [kernel] [1772321.949087] 316864 pages non-shared
Sep 23 02:04:16 [kernel] [1772321.949089] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
            (rest of process list omitted)
Sep 23 02:04:16 [kernel] [1772321.949656] [14579]     0 14579      579      171   5       0             0 rsync
Sep 23 02:04:16 [kernel] [1772321.949662] [14580]     0 14580      677      215   5       0             0 rsync
Sep 23 02:04:16 [kernel] [1772321.949669] [21832]   113 21832    42469    37403   0       0             0 clamd
Sep 23 02:04:16 [kernel] [1772321.949674] Out of memory: Kill process 21832 (clamd) score 4 or sacrifice child
Sep 23 02:04:16 [kernel] [1772321.949679] Killed process 21832 (clamd) total-vm:169876kB, anon-rss:146900kB, file-rss:2712kB

Voici la sortie "top" après avoir répété ma commande rsync en tant qu'utilisateur non root:

top - 03:05:55 up  8:43,  2 users,  load average: 0.04, 0.08, 0.09
Tasks: 224 total,   1 running, 223 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 99.9% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:  33204440k total, 32688600k used,   515840k free,   108124k buffers
Swap:  1959892k total,        0k used,  1959892k free, 31648080k cached

Voici les paramètres de sysctl vm:

# sysctl -a | grep '^vm'
vm.overcommit_memory = 0
vm.panic_on_oom = 0
vm.oom_kill_allocating_task = 0
vm.oom_dump_tasks = 1
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.dirty_background_ratio = 1
vm.dirty_background_bytes = 0
vm.dirty_ratio = 0
vm.dirty_bytes = 15728640
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.nr_pdflush_threads = 0
vm.swappiness = 60
vm.lowmem_reserve_ratio = 256   32      32
vm.drop_caches = 0
vm.min_free_kbytes = 8192
vm.percpu_pagelist_fraction = 0
vm.max_map_count = 65530
vm.laptop_mode = 0
vm.block_dump = 0
vm.vfs_cache_pressure = 100
vm.legacy_va_layout = 0
vm.stat_interval = 1
vm.mmap_min_addr = 4096
vm.vdso_enabled = 2
vm.highmem_is_dirtyable = 0
vm.scan_unevictable_pages = 0
sans date
la source
2
Je ne suis pas un expert en lecture de messages d'erreur du noyau, mais je ne vois aucune indication indiquant que B utilisait 32 Go de mémoire. Avant de partir de l’hypothèse, pouvez-vous confirmer qu’il en est actuellement? Parce qu'il y a une grande différence entre épuiser la mémoire d'une boîte avec 32 Go de cœur et d'une autre avec seulement 4 Go.
MadHatter
Mise à jour avec la sortie Top. C'est après avoir exécuté cette même commande rsync en tant qu'utilisateur non root. Presque tout, sauf 1 Go, est utilisé pour le cache pour le moment.
date
Merci. Comme je l'ai dit, je ne suis pas un expert - mais cela semblait intéressant de vérifier.
MadHatter
vous devez également vérifier que votre noyau autorise le swapping (c.-à-d. que le swapping n'est pas désactivé) (et que vous devez consacrer une plus grande partie de l'espace disque, par exemple 16 Go ou même 32 Go). Certaines personnes étranges sur Internet recommandent de désactiver l'échange, ce qui est très faux.
Olivier Dulac
@OlivierDulac De quel réglage parlez-vous? la prise en charge de swap est compilée ou nous ne serions pas en mesure de monter swap, et le "swappiness" est défini sur 60. En ce qui concerne la taille de la permutation, cela n’aggraverait-il pas le problème, sur un noyau 32 bits? La réponse semble que ce sont les structures de données du noyau qui nous ont tués. Nous n'exécutons pas 32 Go de processus utilisateur, nous voulons juste autant de RAM pour le cache disque, pour la performance.
dataless

Réponses:

178

Lisons donc la sortie de Oom-Killer et voyons ce que l’on peut en tirer.

Lors de l’analyse des journaux de destruction du MOO, il est important d’examiner ce qui l’a déclenchée. La première ligne de votre journal nous donne quelques indices:

[noyau] [1772321.850644] clamd a appelé oom-killer: gfp_mask = 0x84d0, order = 0

order=0nous dit combien de mémoire est demandé. La gestion de la mémoire du noyau ne peut gérer que des nombres de page de puissance égale à 2. Par conséquent, clamd a demandé 2 0 pages de mémoire ou 4 Ko.

Les deux bits les plus bas de GFP_MASK (obtenir un masque de page libre) constituent ce que l'on appelle un masque de zone indiquant à l'allocateur de quelle zone extraire la mémoire :

Flag            value      Description
                0x00u      0 implicitly means allocate from ZONE_NORMAL
__GFP_DMA       0x01u      Allocate from ZONE_DMA if possible
__GFP_HIGHMEM   0x02u      Allocate from ZONE_HIGHMEM if possible

Les zones de mémoire est un concept créé principalement pour des raisons de compatibilité. Dans une vue simplifiée, il existe trois zones pour un noyau x86:

Memory range   Zone       Purpose 

0-16 MB        DMA        Hardware compatibility (devices)
16 - 896 MB    NORMAL     space directly addressable by the Kernel, userland 
> 896 MB       HIGHMEM    userland, space addressable by the Kernel via kmap() calls

Dans votre cas, le zonemask est 0, ce qui signifie que clamd demande de la mémoire à ZONE_NORMAL.

Les autres drapeaux se résolvent à

/*
 * Action modifiers - doesn't change the zoning
 *
 * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt
 * _might_ fail.  This depends upon the particular VM implementation.
 *
 * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
 * cannot handle allocation failures.
 *
 * __GFP_NORETRY: The VM implementation must not retry indefinitely.
 */
#define __GFP_WAIT      0x10u   /* Can wait and reschedule? */
#define __GFP_HIGH      0x20u   /* Should access emergency pools? */
#define __GFP_IO        0x40u   /* Can start physical IO? */
#define __GFP_FS        0x80u   /* Can call down to low-level FS? */
#define __GFP_COLD      0x100u  /* Cache-cold page required */
#define __GFP_NOWARN    0x200u  /* Suppress page allocation failure warning */
#define __GFP_REPEAT    0x400u  /* Retry the allocation.  Might fail */
#define __GFP_NOFAIL    0x800u  /* Retry for ever.  Cannot fail */
#define __GFP_NORETRY   0x1000u /* Do not retry.  Might fail */
#define __GFP_NO_GROW   0x2000u /* Slab internal usage */
#define __GFP_COMP      0x4000u /* Add compound page metadata */
#define __GFP_ZERO      0x8000u /* Return zeroed page on success */
#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
#define __GFP_NORECLAIM  0x20000u /* No realy zone reclaim during allocation */

selon la documentation MM Linux , de sorte que votre requst a les drapeaux pour GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOet GFP_WAIT, étant donc pas particulièrement pointilleux.

Alors quoi de neuf ZONE_NORMAL? Certaines statistiques génériques peuvent être trouvées plus loin dans la sortie du MOO:

[noyau] [1772321.850770] Normal gratuit: 8056ko min: 8048ko bas: 10060ko haut: 12072ko Actif_anon: 0 Ko Actif_anon: 0 Ko Fichier actif: 248 Ko Fichier inactif: 388 Ko

Ce qui freeest remarquable ici, c’est que c’est juste à 8K minet moins low. Cela signifie que le gestionnaire de mémoire de votre hôte est quelque peu en détresse et que kswapd devrait déjà échanger des pages, comme c'est le cas dans la phase jaune du graphique ci-dessous: Graphique du gestionnaire de mémoire Linux

Quelques informations supplémentaires sur la fragmentation de la mémoire de la zone sont données ici:

[noyau] [1772321.850795] Normal: 830 * 4ko 80 * 8ko 0 * 16ko 0 * 32ko 0 * 64ko 0 * 128ko 0 * 256ko 0 * 256kB 0 * 1024ko 0 * 2048ko

indiquant essentiellement que vous avez une seule page contiguë de 4 Mo, le reste étant fortement fragmenté en pages principalement de 4 Ko.

Alors récapitulons:

  • vous avez un processus userland ( clamd) obtenant de la mémoire ZONE_NORMALalors qu'une allocation de mémoire non privilégiée serait généralement effectuée à partirZONE_HIMEM
  • le gestionnaire de mémoire aurait dû, à ce stade, être en mesure de servir la page 4K demandée, bien que vous sembliez avoir une pression mémoire importante ZONE_NORMAL
  • le système, selon kswapdles règles de, aurait dû voir une activité de pagination au préalable, mais rien n’est échangé, même sous la pression de la mémoire ZONE_NORMAL, sans cause apparente
  • Aucun de ce qui précède ne donne une raison précise quant à la raison pour laquelle il oom-killera été invoqué

Tout cela semble assez étrange, mais doit au moins être lié à ce qui est décrit dans la section 2.5 de l'excellent livre "Comprendre le gestionnaire de mémoire virtuelle Linux" de John O'Gorman :

Comme l'espace utilisable par le noyau (ZONE_NORMAL) est limité en taille, le noyau prend en charge le concept de mémoire élevée. [...] Pour accéder à la mémoire entre 1GiB et 4GiB, le noyau mappe temporairement les pages de mémoire vive dans ZONE_NORMAL avec kmap (). [...]

Cela signifie que pour décrire 1 Go de mémoire, il faut environ 11 Mo de mémoire noyau. Ainsi, avec 16 GiB, 176 Mo de mémoire sont consommés, ce qui exerce une pression importante sur ZONE_NORMAL. Cela ne semble pas trop grave tant que d’autres structures utilisant ZONE_NORMAL ne sont pas prises en compte. Même les très petites structures telles que les entrées de table de page (PTE) nécessitent environ 16 Mo dans le pire des cas. Cela fait 16 GiB environ la limite pratique de la mémoire physique disponible Linux sur un x86 .

(c'est moi qui souligne)

Étant donné que 3.2 présente de nombreuses avancées en matière de gestion de la mémoire par rapport à la version 2.6, il ne s’agit pas d’une réponse définitive, mais plutôt d’un indice fort. Réduisez la mémoire utilisable de l'hôte à 16 G maximum au moyen du mem=paramètre kernel ou en extrayant la moitié des modules DIMM du serveur.

En fin de compte, utilisez un noyau 64 bits .

Mec, c'est 2015.

le-wabbit
la source
13
Quand je l' ai dit ci - dessus « Je ne suis pas expert », c'est ce que j'espérais lire. +1000, si je pouvais mais +1 à coup sûr. Quelle bonne réponse!
MadHatter
18
C'était magnifique. Il y a encore de l'espoir pour SF.
Roman
9
@ natale Oui. Je soupçonne que tout votre ZONE_NORMAL est rempli de métadonnées sur les régions de mémoire supérieure. Lorsqu'un processus utilisateur demande des pages de mémoire, il va très probablement demander à ZONE_HIGHMEM (qui peut être mis à niveau par le MM vers ZONE_NORMAL si HIGHMEM n'a plus de pages libres pour servir la demande mais NORMAL l'a), donc à moins que ZONE_HIGHMEM ne soit sous pression mémoire (le vôtre ne l'est pas), ZONE_NORMAL n'aura pas de pages de processus d'espace utilisateur.
le-wabbit
3
[Claque les poings sur le clavier] Donnez cette prime à ce wabbit
underscore_d
3
@ the-wabbit Questions chaudes sur le réseau.
CodesInChaos
4

Quelques choses ...

Ma règle de base pour l’espace de permutation est d’avoir au moins deux fois la quantité de bélier physique. Cela permet au démon page / swap de réorganiser efficacement la mémoire.

Server_B a 32 Go de RAM, essayez donc de le configurer pour 64 Go d’échange. OMI, les 2 Go d’espace de swap dont dispose votre serveur sont beaucoup trop faibles, en particulier pour un serveur.

Si vous ne pouvez pas transformer une partition supplémentaire en une partition swap, vous pouvez le tester en créant un fichier et en le montant en tant que partition swap [ce sera lent]. Voir https://www.maketecheasier.com/swap-partitions-on-linux/

Etant donné que server_B dispose de beaucoup d'espace disque, --inplace n'est pas nécessaire et peut être indésirable, car c'est peut-être ce qui a poussé rsync à utiliser 32 Go. --inplace n'est vraiment utile que si vous manquez d'espace disque (que vous n'êtes pas) ou si vous avez des exigences de performances particulières.

Je suppose que rsync voudra utiliser 50 Go de ram [taille du fichier] avec vos options actuelles. Normalement, rsync n'a pas besoin de beaucoup de mémoire pour faire son travail, donc une ou plusieurs de vos options peuvent être le problème. Je transfère régulièrement des fichiers de 200 Go sans problème.

Faites quelques essais sans options. Faites cela avec des fichiers plus petits, par exemple 10 Go - cela devrait éviter la panique du noyau, tout en vous permettant de surveiller le comportement à l'origine du problème. Surveillez l'utilisation de la mémoire de rsync.

Ajoutez graduellement des options, une à la fois, pour voir quelle option [ou combinaison d’options] a pour effet que rsync commence à tirer parti de la mémoire vive (par exemple, pendant le transfert, l’utilisation de RAM par rsync augmente proportionnellement à la quantité de données de fichier transférées, etc.).

Si vous avez vraiment besoin des options qui permettent à rsync de conserver une image de fichier dans la RAM, vous aurez besoin d'un espace de swap supplémentaire et votre taille de fichier maximale sera limitée en conséquence.

Quelques autres choses [MISE À JOUR]:

(1) La trace de pile dans le noyau montre que rsync était défectueux sur une zone mmap. Il s’agit probablement de copier le fichier. mmap n'assure aucune garantie de vidage du disque tant que le fichier n'est pas fermé [contrairement à lecture / écriture], qui passe immédiatement au cache de bloc FS [où il sera vidé]

(2) La panne / panique du noyau se produit lorsque la taille du transfert atteint la taille de la RAM. Clairement, rsync récupère une grande partie de la mémoire non fscache via malloc ou mmap. Encore une fois, avec les options que vous avez spécifiées, rsync allouera 50 Go de mémoire pour transférer un fichier de 50 Go.

(3) Transférez un fichier de 24 Go. Cela fonctionnera probablement. Ensuite, démarrez le noyau avec mem = 16G et relancez le test du fichier de 24 Go. Il va souffler à 16 Go plutôt que 32 Go. Cela confirmera que rsync a vraiment besoin de mémoire.

(4) Avant de dire que l'ajout de swap est ridicule, essayez d'ajouter des [via la méthode swap-to-file]. C'est beaucoup plus facile à faire et à tester que tous les arguments théoriques sur le fait que l'échange n'est pas nécessaire. Même si ce n'est pas la solution, vous pouvez en apprendre quelque chose. Je parie que le test mem = 16G réussira sans panique / crash.

(5) Il est probable que rsync se déclenche, mais il est trop rapide de voir en haut avant que OOM n'entre en jeu et ne supprime plus rsync. Lorsque rsync atteint 32 Go, d’autres processus ont déjà été contournés, notamment s’ils sont inactifs. Peut-être, une combinaison de "gratuit" et "haut" vous donnera une meilleure image.

(6) Une fois que rsync a été tué, il faut du temps pour vider mmap du FS. Pas assez vite pour OOM et cela commence à tuer d'autres choses (certaines sont évidemment critiques). C’est-à-dire que le flush mmap et le MOO sont en course. Ou, OOM a un bug. Sinon, il n'y aurait pas de crash.

(7) D'après mon expérience, lorsqu'un système "heurte la mémoire", la récupération complète prend beaucoup de temps. Et, parfois, il ne récupère jamais vraiment correctement et le seul moyen de l'effacer est un redémarrage. Par exemple, j'ai 12 Go de RAM. Lorsque j'exécute un travail qui utilise 40 Go de mémoire (puis que je le supprime, il faut environ 10 minutes au système pour revenir à une réactivité normale [avec le voyant du disque allumé en permanence]. .

(8) Exécuter rsync sans options. Cela fonctionnera. Obtenez un exemple de base sur lequel travailler. Ajoutez ensuite --inplace et refaites le test. Ensuite, faites --append-verify à la place. Ensuite, essayez les deux. Découvrez quelle option permet à rsync de réaliser l’immense mmap. Ensuite, décidez si vous pouvez vivre sans elle. Si --inplace est le coupable, c'est une évidence, car vous disposez de beaucoup d'espace disque. Si vous devez avoir l'option, vous devrez obtenir l'espace d'échange pour accueillir le malloc / mmap que rsync fera.

DEUXIÈME MISE À JOUR:

S'il vous plaît faire le mem = et petits tests de fichiers de ce qui précède

Les questions centrales: Pourquoi rsync est-il tué par le MOO? Qui / Qu'est-ce que mâcher de la mémoire?

J'ai lu [mais j'ai oublié] que le système fonctionne en 32 bits. Donc, je suis d’accord, rsync ne peut pas être directement responsable (via malloc / mmap - glibc implémente de grands mallocs via des mmaps anonymes / privés), et la défaillance de la page, mmap de rsync, ne déclenche que par hasard. Ensuite, OOM calcule la mémoire totale consommée par rsync directement et indirectement [cache FS, mémoires tampons de sockets, etc.] et décide que c'est le candidat principal. Il peut donc être utile de surveiller l'utilisation totale de la mémoire. Je soupçonne que cela progresse au même rythme que le transfert de fichiers. Évidemment, cela ne devrait pas.

Certaines choses que vous pouvez surveiller dans / proc ou / proc / rsync_pid via un script perl ou python dans une boucle rapide [un script bash ne sera probablement pas assez rapide pour l'événement de fin du monde] qui peut tout surveiller plusieurs centaines de fois / sec. Vous pouvez exécuter cette opération avec une priorité plus élevée que rsync afin qu'elle reste dans la mémoire vive et puisse être surveillée de manière à pouvoir surveiller les événements juste avant le crash et, espérons-le, pendant le MOO afin que vous puissiez voir pourquoi le MOO devient fou:

/ proc / meminfo - pour obtenir un grain plus fin sur l'utilisation de l'échange au "point d'impact". En fait, il peut être plus utile d’obtenir le nombre final de la quantité totale de RAM utilisée. Bien que top fournisse cela, il se peut qu’il ne soit pas assez rapide pour afficher l’état de l’univers juste avant le "Big Bang" (par exemple, les 10 dernières millisecondes)

/ proc / rsync_pid / fd. La lecture des liens symboliques vous permettra d’identifier quel fd est ouvert sur le fichier cible (par exemple, readlink de / proc / rsync_pid / fd / 5 -> target_file). Cela ne doit probablement être fait qu'une fois pour obtenir le numéro fd [il devrait rester fixe]

Connaissant le numéro fd, regardez / proc / rsync_pid / fdinfo / fd. C'est un fichier texte qui ressemble à:

pos: <position_fichier>
drapeaux: blah_blah
mnt_id: blah_blah

Surveiller la valeur "pos" peut être utile, car la "position du dernier fichier" peut être utile. Si vous effectuez plusieurs tests avec différentes tailles et options mem =, la dernière position du fichier en suit-elle [et comment]? Le suspect habituel: position du fichier == RAM disponible

Mais le moyen le plus simple est de commencer par "serveur rsync fichier_local: fichier_distant" et de vérifier que cela fonctionne. Vous pourrez peut-être obtenir des résultats similaires [mais plus rapides] en faisant "serveur ssh rsync fichier_a fichier_b" [vous devez d'abord créer un fichier 50 Go]. Un moyen simple de créer file_a est scp local_system: original_file server: file_a et cela pourrait être intéressant en soi (par exemple, cela fonctionne-t-il lorsque rsync se bloque? Si scp fonctionne, mais que rsync échoue, cela renvoie à rsync. Si scp échoue, cela signifie à quelque chose d'autre comme le pilote de la carte réseau). Faire ssh rsync retire également la carte réseau de l’équation, ce qui peut être utile. Si cela bloque le système, alors quelque chose ne va vraiment pas. Si cela réussit, [comme je l'ai mentionné] commence à rajouter les options une par une.

Je n'aime pas trop insister sur ce point, mais l'ajout de swap via swap-to-file peut changer / retarder le comportement du crash et peut s'avérer utile en tant qu'outil de diagnostic. Si l'ajout, disons de 16 Go, de swap retarde le crash [mesuré par l'utilisation de la mémoire ou la position du fichier cible] de 32 Go à 46 Go, cela dit quelque chose.

Ce n'est peut-être pas un processus particulier, mais un pilote de noyau errant qui mâche de la mémoire. Le vmalloc interne du noyau alloue des éléments qui peuvent être échangés. IIRC, il n’est pas lié par l’adressabilité en toutes circonstances.

Clairement, le MOO est en train de devenir confus / paniqué. Cela tue rsync, mais ne voit pas la mémoire libérée rapidement et cherche d'autres victimes. Certains d'entre eux sont probablement essentiels au fonctionnement du système.

Malloc / mmap mis à part, cela pourrait être dû à un cache FS non vidé qui prend beaucoup de temps (par exemple, avec 30 Go de données non vidées, avec un débit de disque de 300 Mo / s, le vidage peut prendre 100 secondes). Même à ce rythme, OOM peut être trop impatient. Ou bien, le meurtre de rsync par OOM ne déclenche pas assez rapidement la chasse de FS. Le vidage du FS se produit assez rapidement, mais il comporte une version "paresseuse" des pages dans le pool libre. Vous pouvez définir certaines options / proc pour contrôler le comportement du cache FS [je ne me souviens plus de ce qu’elles sont].

Essayez de démarrer avec mem = 4G ou un autre petit nombre. Cela pourrait réduire le cache FS et raccourcir son temps de vidage pour empêcher le MOO de chercher d'autres choses à tuer (par exemple, le temps de vidage est réduit de 100 à <1 s). Cela peut également permettre de démasquer un bogue de MOO qui ne peut pas gérer un RAM physique> 4 Go sur un système 32 bits ou autre.

En outre, un point important: Exécuter en tant que non-root. Les utilisateurs root ne sont jamais censés mâcher des ressources, ce qui leur donne plus de limites indulgentes (par exemple, 99% de mémoire contre 95% pour les utilisateurs non root). Cela peut expliquer pourquoi OOM est dans un tel état. En outre, cela donne OOM et. Al. plus de marge pour faire son travail de récupération de la mémoire.

Craig Estey
la source
Voir Combien d’espace SWAP sur un système à mémoire vive? - et vous ne voulez pas que votre système utilise 63 Go d’échange. Ce ne sera pas utilisable.
Réintégrer Monica - M. Schröder le
1
swap> RAM n’est vraiment utile que si vous exécutez sans VM surcommit, le noyau doit donc réserver l’espace de swap pour les pages allouées jusqu’à ce qu’elles soient souillées et que de vraies pages physiques soient sauvegardées. La pratique actuelle consiste à autoriser un engagement excessif et à utiliser une petite quantité d'espace d'échange pour mettre en page des pages qui n'ont été touchées qu'au démarrage et qui ne sont pas nécessaires en fonctionnement normal. surcommit = 0 avec un petit échange est acceptable si vous avez beaucoup de RAM, pour la plupart des systèmes.
Peter Cordes
Il semble que rsync vraiment est d' essayer d'utiliser> 32GB, de sorte que le swap est nécessaire pour cela. C'est-à-dire que rsync utilisera 50 Go pour ce fichier. La mesure 2x est une métrique éprouvée depuis 30 ans. Comme un disque de 6 To coûte environ 300 dollars, il n’ya aucune raison de ne pas le faire. Quoi d'autre peut être en cours d'exécution sur ce serveur qui va collectivement dépasser la limite de RAM?
Craig Estey
1
@CraigEstey 64 Go de swap est complètement ridicule puisque, comme je l’ai dit plus tôt, nous n’avons pas de processus utilisateur volumineux, nous voulons seulement le cache disque et, comme mon journal l’a montré, nous utilisions le swap ZERO au moment du crash. ZÉRO. De plus, rsync utilise 600 Ko de RAM, même sur un fichier de 50 Go. Ma confusion initiale était que peut-être Linux souscrivait agressivement au cache disque. Et enfin, je veux voir des chiffres ou de la documentation sur la quantité de mémoire utilisée par le noyau pour suivre son espace d’échange avant d’en ajouter plus à cette boîte.
date
@dataless J'ai ajouté des informations supplémentaires qui expliquent en détail ce qui se passe et pourquoi. rsync est saisissant la mémoire via malloc / mmap et il sera pour 50Go avant qu'il ne soit fait. Voir la section mise à jour. Il a des tests qui peuvent prouver / réfuter ce que je dis et vous pouvez ignorer le swap ajouté à tester initialement. BTW, j'ai kernels / pilotes programmation depuis plus de 40 ans - je pourrais juste savoir quelque chose que vous ne pas, donc le ton s'il vous plaît modérer - Je suis en train d'aider.
Craig Estey
2

clamd? On dirait que vous utilisez ClamAV et que le contrôle sur accès est activé lorsque le moteur antivirus tente de rechercher la présence de virus dans les fichiers ouverts, en chargeant en mémoire le contenu intégral de chaque fichier ouvert par tout autre processus .

En fonction de votre sécurité et de la nécessité de ce transfert, vous devez envisager de désactiver le contrôle sur accès ClamAV pendant le transfert.

oo.
la source
Je ne savais pas que c’était même une chose que clamav pouvait faire… mais non, nous ne numérisons que des fichiers spécifiques acheminés à partir de clamc. Aussi, 32 bits, donc pas de risque de Clamav monopolisant toute la mémoire système. (Vous voyez pourquoi nous pensions que 32 bits était toujours une bonne idée?)
données
1
Le noyau Linux indique que clamd est le processus dont les demandes d'allocation de mémoire invoquent le tueur de MOO. ClamAV est presque certainement la cause secondaire (la cause principale étant le manque de mémoire). Qu'il s'agisse du contrôle sur accès ou d'une autre configuration, tous les signes indiquent ClamAV.
oo.
La prochaine fois que vous lancerez rsync, lancez top et surveillez la taille de résident du processus clamd.
oo.
clamd a été le premier processus à invoquer le tueur à mort, mais aussi le premier à y être mort puisqu'il pèse près de 42 Mo (un des processus les plus importants sur le serveur). Oom_killer est exécuté à plusieurs reprises après cela jusqu'à ce que même Metalog soit tué.
date