Vraag Rsync heeft Linux OOM-moordenaar geactiveerd op een enkel 50 GB-bestand


Ik heb een enkel 50 GB-bestand op server_A en ik kopieer het naar server_B. ik ren

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

Server_B heeft 32 GB RAM met 2 GB-swap. Het is meestal inactief en zou veel vrije RAM moeten hebben gehad. Het heeft voldoende schijfruimte. Bij ongeveer 32 GB wordt de overdracht afgebroken omdat de externe kant de verbinding heeft gesloten.

Server_B is nu van het netwerk afgezet. We vragen het datacenter om het opnieuw op te starten. Wanneer ik kijk naar het kernellogboek van voordat het crashte, zag ik dat het 0 bytes swap gebruikte, en de proceslijst gebruikte heel weinig geheugen (het rsync-proces werd vermeld als 600 KB RAM), maar de oom_killer was wild gaan, en het laatste wat in het logboek staat is waar het het kernel-leesproces van metalog doodt.

Dit is kernel 3.2.59, 32-bit (dus geen proces kan sowieso meer dan 4 GB toewijzen).

Het lijkt bijna alsof Linux meer prioriteit geeft aan caching dan aan langdraaiende daemons. Wat geeft?? En hoe kan ik voorkomen dat het weer gebeurt?

Hier is de uitvoer van 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

Hier is de 'top'-uitvoer na het herhalen van mijn rsync-opdracht als een niet-rootgebruiker:

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

Dit zijn de parameters van 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

65
2017-09-24 06:36


oorsprong


Ik ben geen expert in het lezen van kernelcrashberichten, maar ik zie daar geen indicatie dat B 32 GB aan kern gebruikte. Voordat we verder gaan met de veronderstelling dat dit zo was, kunt u bevestigen dat dit momenteel zo is? Omdat er een groot verschil is tussen geheugenuitputting van een doos met 32 ​​GB kern en één met slechts 4 GB. - MadHatter
Bijgewerkt met Top-uitvoer. Dit is na het uitvoeren van diezelfde rsync-opdracht als een niet-rootgebruiker. Vrijwel alles behalve 1 GB wordt nu voor cache gebruikt. - dataless
Bedankt. Zoals ik al zei, ik ben geen expert, maar het leek het waard om te controleren. - MadHatter
je moet ook controleren of je kernel wel toestaat om te swappen (dat wil zeggen, ruilen is niet uitgeschakeld) (en je zou een groter stuk schijfruimte moeten inzetten, laten we zeggen 16 Gb of zelfs 32 Gb). Sommige rare personen op het net raden aan om ruilen uit te schakelen, wat erg verkeerd is. - Olivier Dulac
@ Olivier Dulac naar welke instelling verwijst u? swap-ondersteuning is gecompileerd of we zouden swap niet kunnen aankoppelen, en de 'swappiness' is ingesteld op 60. Wat betreft de swap-grootte, zou dat niet alleen het probleem alleen maar erger maken, op een 32-bits kernel? Het antwoord lijkt dat kerneldatastructuren ons hebben gedood. We hebben geen 32 GB aan gebruikersprocessen, we willen gewoon zoveel ram voor schijfcache, voor prestaties. - dataless


antwoorden:


Dus laten we de oom-killer-uitvoer lezen en zien wat daar van te leren is.

Bij het analyseren van OOM-killer-logbestanden is het belangrijk om te kijken naar wat het heeft geactiveerd. De eerste regel van uw log geeft ons enkele aanwijzingen:

[kernel] [1772321.850644] clamd heeft oom-killer aangeroepen: gfp_mask = 0x84d0, order = 0

order=0 vertelt ons hoeveel geheugen wordt gevraagd. Het geheugenbeheer van de kernel kan alleen paginanummers beheren met de machten van 2, dus clamd heeft 2 aangevraagd0 pagina's geheugen of 4 KB.

De laagste twee bits van het GFP_MASK (get free page mask) vormen de zogenaamde zonemasker  de toewijzer vertellen naar welke zone het geheugen moet worden opgehaald:

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

Geheugenzones is een concept dat voornamelijk is gemaakt om compatibiliteitsredenen. In een vereenvoudigde weergave zijn er drie zones voor een x86-kernel:

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

In uw geval is het zonemasker 0, wat betekent dat clamd om geheugen vraagt ZONE_NORMAL.

De andere vlaggen lossen op

/*
 * 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 */

volgens de Linux MM-documentatie, dus jouw verzoek heeft de vlaggetjes voor GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IO en GFP_WAIT, dus niet bijzonder kieskeurig.

Dus wat is er aan de hand ZONE_NORMAL? Enkele generieke statistieken zijn verderop in de OOM-uitvoer te vinden:

[kernel] [1772321.850770] Normaal gratis: 8056kB min: 8048kB laag: 10060kB hoog: 12072kB active_anon: 0kB inactive_anon: 0kB active_file: 248kB inactive_file: 388kB unevictable: 0kB isolated (anon)   : 0kB geïsoleerd (bestand): 0kB aanwezig: 890008kB

Merkbaar hier is dat free is slechts 8K van min en ver onder low. Dit betekent dat de geheugenbeheerder van je host enigszins in nood is en dat kswapd al pagina's moet omwisselen zoals in de geel fase van de onderstaande grafiek: Linux memory manager graph

Meer informatie over de fragmentatie van het geheugen van de zone wordt hier gegeven:

[kernel] [1772321.850795] Normaal: 830 * 4kB 80 * 8kB 0 * 16kB 0 * 32kB 0 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 1 * 4096kB = 8056kB

in feite dat je een enkele aaneengesloten pagina van 4 MB hebt en de rest zwaar gefragmenteerd in voornamelijk 4 KB-pagina's.

Dus laten we recapituleren:

  • je hebt een userland-proces (clamd) geheugen ophalen ZONE_NORMAL overwegende dat niet-bevoorrechte geheugentoewijzing meestal wordt uitgevoerd vanaf ZONE_HIMEM
  • de geheugenbeheerder zou in dit stadium de gevraagde 4K-pagina moeten kunnen bedienen, hoewel u blijkbaar een aanzienlijke geheugendruk heeft ZONE_NORMAL
  • het systeem, door kswapdde regels, moeten heb van tevoren wat paging-activiteit gezien, maar er wordt niets uitgewisseld, zelfs niet onder druk van geheugen ZONE_NORMAL, zonder duidelijke oorzaak
  • Geen van bovenstaande geeft een duidelijke reden waarom oom-killer is aangeroepen

Dit lijkt allemaal nogal vreemd, maar moet op zijn minst gerelateerd zijn aan wat er in wordt beschreven deel 2.5 van het uitstekende boek "Understanding the Linux Virtual Memory Manager" van John O'Gorman:

Omdat de adresruimte die bruikbaar is voor de kernel (ZONE_NORMAL) beperkt is in omvang, heeft de kernel ondersteuning voor het concept van hoog geheugen. [...] Om toegang te krijgen tot het geheugen tussen het bereik van 1GiB en 4GiB, wijst de kernel tijdelijk pagina's van hoog geheugen naar ZONE_NORMAL met kmap (). [...]

Dat betekent dat voor het beschrijven van 1GiB geheugen, ongeveer 11MiB kernelgeheugen vereist is. Dus met 16GiB wordt 176MiB geheugen verbruikt, waardoor ZONE_NORMAL aanzienlijk onder druk komt te staan. Dit klinkt niet slecht totdat er andere structuren in aanmerking worden genomen die ZONE_NORMAL gebruiken. Zelfs zeer kleine structuren zoals paginatabelvermeldingen (PTE's) vereisen in het ergste geval ongeveer 16MiB. Dit maakt 16GiB over de praktische limiet voor beschikbaar fysiek geheugen Linux op een x86.

(nadruk ligt van mij)

Aangezien 3.2 veel vooruitgang heeft in geheugenbeheer boven 2.6, is dit geen definitief antwoord, maar een echt sterke hint die ik als eerste zou nastreven. Verklein het bruikbare geheugen van de host tot maximaal 16G door het gebruik van de mem= kernelparameter of door de helft van de DIMM's uit de server te rippen.

uiteindelijk, gebruik een 64-bits kernel.

Kerel, het is 2015.


179
2017-09-24 10:46



Toen ik zei hierboven "Ik ben geen expert", deze is wat ik hoopte te lezen. +1000, als ik maar kon; +1 zeker. Wat een geweldig antwoord! - MadHatter
Dat was mooi. Er is nog steeds hoop voor SF. - Roman
@dataless Ja. Ik vermoed dat al je ZONE_NORMAL is gevuld met metadata over de bovenste geheugengebieden. Wanneer een userland-proces geheugenpagina's aanvraagt, zal het hoogstwaarschijnlijk ZONE_HIGHMEM aanvragen (dit kan door de MM worden opgewaardeerd naar ZONE_NORMAL als HIGHMEM geen gratis pagina's meer heeft om het verzoek te verwerken, maar NORMAL heeft), tenzij ZONE_HIGHMEM onder geheugendruk staat (de jouwe is dat niet), ZONE_NORMAL zal geen pagina's van gebruikersruimte-processen hebben. - the-wabbit
[slams op toetsenbord] Geef deze wabbit de bounty - underscore_d
@ the-wabbit Vragen over het warme netwerk. - CodesInChaos


Een paar dingen ...

Mijn vuistregel voor swap space is om minimaal 2x de hoeveelheid fysieke ram te hebben. Hierdoor kan de page / swap-daemon de mogelijkheid hebben om het geheugen efficiënt te herstellen.

Server_B heeft 32 GB RAM, dus probeer het te configureren voor 64 GB swap. IMO, de 2 GB swapruimte die je server heeft is manier te laag, vooral voor een server.

Als je geen extra partitie hebt die je in een swap-partitie kunt maken, kun je dit testen door een bestand te maken en het als een swap-partitie te monteren [het zal traag zijn]. Zien https://www.maketecheasier.com/swap-partitions-on-linux/

Omdat server_B over voldoende schijfruimte beschikt, is --inplace niet nodig en mogelijk ongewenst, omdat rsync mogelijk 32 GB gaat gebruiken. --inplace is alleen erg handig als je te weinig ruimte op het bestandssysteem hebt [wat je niet bent] of een speciale prestatie-eis hebt.

Mijn gok is dat rsync 50 GB ram [de bestandsgrootte] wil gebruiken met je huidige opties. Normaal gesproken heeft rsync niet zoveel geheugen nodig om zijn werk te doen, dus een of meer van uw opties kan het probleem zijn. Ik draag routinematig 200GB-bestanden zonder probleem over.

Voer enkele testritten uit waarbij geen opties worden gebruikt. Doe dit met kleinere bestanden, zeg 10 GB - dit zou de kernel paniek moeten voorkomen, maar laat je toch toe om het gedrag te volgen dat het probleem veroorzaakt. Controleer het geheugengebruik van rsync.

Voeg stap voor stap back-opties één voor één toe om te zien welke optie [of combinatie van opties] ervoor zorgt dat rsync op de RAM begint uit te barsten (bijv. Terwijl de overdracht plaatsvindt, neemt het ramgebruik van rsync evenredig toe met de hoeveelheid overgedragen bestandsgegevens, enz.).

Als je echt de opties nodig hebt die ervoor zorgen dat rsync een bestandimage in het RAM-geheugen behoudt, heb je de extra swapruimte nodig en wordt je maximale bestandsgrootte dienovereenkomstig beperkt.

Nog een paar dingen [BIJGEWERKT]:

(1) De traceerback van de kernelstapel laat zien dat rsync pagina-fouten veroorzaakte op een mmap-gebied. Het is waarschijnlijk het bestand aan het verkleinen. mmap biedt geen garantie dat het naar schijf wordt doorgestuurd tot het bestand is gesloten [in tegenstelling tot lezen / schrijven] dat direct naar de FS-blokcache gaat [waar het zal worden gespoeld]

(2) De kernelcrash / paniek treedt op wanneer de overdrachtsgrootte de grootte van het RAM-geheugen raakt. Het is duidelijk dat rsync zoveel niet-fscache-geheugen opvangt via malloc of mmap. Nogmaals, met de opties die je hebt opgegeven, zal rsync 50 GB geheugen toewijzen om een ​​bestand van 50 GB over te zetten.

(3) Draag een 24GB-bestand over. Dat zal waarschijnlijk werken. Start dan de kernel op met mem = 16G en voer de 24GB bestandstest opnieuw uit. Het zal uitbarsten bij 16 GB in plaats van 32 GB. Dit zal bevestigen dat rsync echt het geheugen nodig heeft.

(4) Voordat je zegt dat het toevoegen van swap belachelijk is, probeer dan wat toe te voegen [via de methode swap-to-file]. Dit is veel gemakkelijker om te doen en te testen dan alle academische argumenten over hoe swap niet vereist is. Zelfs als het niet de oplossing is, kun je er iets van leren. Ik wed dat mem = 16G-test zal slagen zonder een paniek / crash.

(5) De kans bestaat dat rsync is het raken van swap, maar het gebeurt te snel om van boven te zien voordat OOM begint en rsync doodt. Tegen de tijd dat rsync 32 GB bereikt, zijn andere processen al gedwongen om te ruilen, vooral als ze niet actief zijn. Misschien geeft een combinatie van "gratis" en "top" u een beter beeld.

(6) Nadat rsync is gedood, kost het tijd om mmap naar de FS door te spoelen. Niet snel genoeg voor OOM en het begint andere dingen te doden [sommige zijn duidelijk van cruciaal belang voor de missie]. Dat wil zeggen, de mmap flush en OOM racen. Of OOM heeft een bug. Anders zou er geen crash zijn.

(7) Naar mijn ervaring duurt het een lange tijd voordat Linux volledig is hersteld als een systeem "de geheugenmuur raakt". En soms herstelt het nooit echt en de enige manier om het op te ruimen is een herstart. Ik heb bijvoorbeeld 12 GB RAM. Wanneer ik een taak voer die 40 GB geheugen gebruikt [ik heb 120 GB swap voor grote taken] en deze vervolgens dood, duurt het ongeveer 10 minuten voordat het systeem weer normaal reageert [met het schijflampje constant aan] .

(8) Voer rsync uit zonder opties. Dit zal werken. Ontvang een baseline om van te werken. Voeg vervolgens terug --inplace en test opnieuw. Doe dan - bevestig - controleer in plaats daarvan. Probeer dan allebei. Ontdek welke optie rsync de enorme mmap oplevert. Beslis dan of je zonder kunt leven. Als --inplace de boosdoener is, is dat geen goed idee, want je hebt voldoende schijfruimte. Als je de optie moet hebben, moet je de swap ruimte krijgen om de malloc / mmap die rsync zal doen te herbergen.

TWEEDE UPDATE:

Doe de mem = en kleinere bestandstests uit het bovenstaande.

De centrale vragen: Waarom wordt rsync gedood door OOM? Wie / Wat is kauwgeheugen?

Ik las [maar was vergeten] dat het systeem 32 bits is. Dus, ik ben het ermee eens, rsync is mogelijk niet direct verantwoordelijk (via malloc / mmap - glibc implementeert grote mallocs via anonieme / private mmaps) en de mmap-paginafout van rsync triggert OOM toevallig door toeval. Vervolgens berekent OOM het totale geheugen dat rsync direct en indirect verbruikt [FS-cache, socketbuffers, enzovoort] en besluit dat het de hoofdkandidaat is. Het bewaken van het totale geheugengebruik kan dus nuttig zijn. Ik vermoed dat het in hetzelfde tempo kruipt als de bestandsoverdracht. Het is duidelijk dat het niet zou moeten.

Sommige dingen die u in / proc of / proc / rsync_pid kunt volgen via een perl- of pythonscript in een snelle lus [een bash-script zal waarschijnlijk niet snel genoeg zijn voor het einde van de wereld] dat alle de volgende honderden keren / sec. Je kunt dit op een hogere prioriteit uitvoeren dan rsync, zodat het zichzelf in het RAM-geheugen en de werking ervan houdt, zodat je dingen kunt controleren vlak voor de crash en hopelijk tijdens OOM, zodat je kunt zien waarom OOM gek wordt:

/ proc / meminfo - om meer fijne korrels te krijgen voor het gebruik van de swap op "point of impact". Het is misschien nuttiger om het laatste nummer te krijgen van hoeveel RAM er wordt gebruikt. Hoewel top dit biedt, is het misschien niet snel genoeg om de status van het universum weer te geven net voor de 'oerknal' (bijvoorbeeld de laatste 10 milliseconden)

/ proc / rsync_pid / fd-map. Als u de symlinks leest, kunt u bepalen welke fd wordt geopend in het doelbestand (bijvoorbeeld readlink van / proc / rsync_pid / fd / 5 -> target_file). Dit hoeft waarschijnlijk maar één keer gedaan te worden om het fd-nummer te krijgen [het moet vast blijven]

Als u het fd-getal kent, kijkt u naar / proc / rsync_pid / fdinfo / fd. Het is een tekstbestand dat eruit ziet als:

pos: <bestandspositie>
vlaggen: blah_blah
mnt_id: blah_blah

Het bewaken van de "pos" -waarde kan nuttig zijn, omdat de "laatste bestandspositie" nuttig kan zijn. Als u verschillende tests met verschillende grootten en mem = opties uitvoert, houdt de laatste bestandspositie dan een van deze [en hoe] bij? De gebruikelijke verdachte: bestandspositie == beschikbare RAM

Maar de eenvoudigste manier is om te beginnen met "rsync local_file server: remote_file" en te controleren of dat werkt. U kunt soortgelijke [maar snellere] resultaten krijgen door "ssh server rsync file_a file_b" [u moet eerst een bestand van 50 GB te maken]. Een eenvoudige manier om file_a aan te maken is scp local_system: original_file server: file_a en dit kan interessant zijn op zichzelf (bijvoorbeeld werkt dit wanneer de rsync crasht? Als scp werkt, maar rsync mislukt, wijst dit naar rsync. Als scp mislukt, worden deze punten naar iets anders zoals de driver van de NIC). Als de ssh rsync wordt uitgevoerd, wordt ook de NIC uit de vergelijking gehaald, wat nuttig kan zijn. Als dat het systeem slangen, dan is er echt iets mis. Als het lukt, begin ik [zoals ik heb genoemd] de opties één voor één toe te voegen.

Ik haat het om het punt te herzien, maar het toevoegen van een swap via swap-to-file kan het crashgedrag veranderen / vertragen en kan nuttig zijn als een diagnostisch hulpmiddel. Als het toevoegen van bijvoorbeeld 16 GB aan swap de crash [zoals gemeten door geheugengebruik of doelpositie] vertraagt ​​van 32 GB naar 46 GB, dan zegt dat iets.

Het is misschien geen specifiek proces, maar een dwalende kerneldriver die op geheugen kauwt. De interne vmalloc van de kernel wijst spullen toe en het kan worden uitgewisseld. IIRC, het is onder alle omstandigheden niet gebonden aan adresgevoeligheid.

Het is duidelijk dat de OOM verward / in paniek raakt. Dat wil zeggen, het doodt rsync, maar ziet niet dat het geheugen op tijd wordt vrijgegeven en gaat op zoek naar andere slachtoffers. Sommigen van hen zijn waarschijnlijk van cruciaal belang voor de werking van het systeem.

malloc / mmap terzijde, dit kan worden veroorzaakt door niet-uitgebouwde FS-cache die lang duurt (bijvoorbeeld met 30 GB ongecouroseerde gegevens, uitgaande van een schijfsnelheid van 300 MB / sec, het kan 100 seconden duren om deze leeg te spoelen). Zelfs in dat tempo kan OOM te ongeduldig zijn. Of OOM-kill-rsync start de FS-flush niet snel genoeg [of helemaal niet]. Of FS flush gebeurt snel genoeg, maar het heeft een "luie" release van de pagina's terug naar de gratis pool. Er zijn enkele / proc-opties die u kunt instellen om het FS-cachegedrag te beheren [ik kan me niet herinneren wat ze zijn].

Probeer te booten met mem = 4G of een ander klein getal. Dit kan de FS-cache verminderen en de spoeltijd verkorten om te voorkomen dat OOM andere dingen zoekt om te doden (de spoeltijd wordt bijvoorbeeld teruggebracht van 100 sec tot <1 sec). Het kan ook een OOM-bug ontmaskeren die een fysieke ram> 4 GB op een 32-bits systeem of iets dergelijks niet aankan.

Ook een belangrijk punt: uitvoeren als niet-root. Van rootgebruikers wordt nooit verwacht dat ze op bronnen kauwen, zodat ze meer vergevingsgezinde limieten krijgen (bijvoorbeeld 99% van het geheugen versus 95% voor niet-rootgebruikers). Dit kan verklaren waarom OOM zich in een dergelijke staat bevindt. Ook geeft dit OOM et. al. meer hoofdruimte om zijn werk te doen om het geheugen terug te winnen.


4
2017-09-27 20:30



Zien Hoeveel SWAP-ruimte op een hoog geheugensysteem? - en je wilt niet dat je systeem 63 GB swap gebruikt. Het zal niet bruikbaar zijn. - Martin Schröder
swap> RAM is alleen echt handig als je zonder VM overcommit uitvoert, dus de kernel moet swap-ruimte reserveren voor toegewezen pagina's totdat ze vervuild zijn en echte fysieke pagina's nodig hebben die ze ondersteunen. De huidige praktijk is om overcommit te laten werken en met een kleine hoeveelheid swapruimte naar pagina-uitpagina's te lopen die alleen werden aangeraakt bij het opstarten en die niet nodig zijn bij normaal gebruik. overcommit = 0 met kleine swap is prima als je veel RAM hebt, voor de meeste systemen. - Peter Cordes
Het lijkt erop dat rsync echt is proberen te gebruiken> 32 GB, dus daarvoor is de swap nodig. Dat wil zeggen, rsync gaat 50 GB gebruiken voor dit bestand. De 2x is al 30 jaar een beproefde statistiek. Omdat een 6TB-schijf ~ $ 300 is, is er geen reden om dat niet te doen. Wat kan er nog meer op deze server worden uitgevoerd die collectief de RAM-limiet overschrijdt? - Craig Estey
@CraigEstey 64 GB swap is volkomen belachelijk, omdat ik, zoals ik eerder zei, geen grote gebruikersprocessen heeft, we alleen de schijfcache willen, en zoals mijn logboek liet zien, gebruikten we de ZERO-swap op het moment van de crash. NUL. Ook gebruikt rsync 600 KB ram zelfs op een bestand van 50 GB. Mijn eerste verwarring was dat linux misschien agressief vasthield aan de schijfcache. En tot slot wil ik een aantal cijfers of documentatie zien over hoeveel geheugen de kernel gebruikt om zijn swap-ruimte bij te houden voordat ik meer aan dit vak zou toevoegen. - dataless
@dataless Ik heb aanvullende informatie toegevoegd die volledig verklaart wat er gebeurt en waarom. rsync is het geheugen ophalen via malloc / mmap en het zal 50 GB duren voordat het klaar is. Zie de bijgewerkte sectie. Het heeft tests die kunnen bewijzen / weerleggen wat ik zeg en je kunt de toegevoegde wissel aanvankelijk overslaan om te testen. Trouwens, ik programmeer al meer dan 40 jaar kernels / drivers - ik weet misschien iets dat je niet doet, dus gematigde toon - ik ben proberen te helpen. - Craig Estey


clamd? Het lijkt erop dat u ClamAV gebruikt en dat scannen met toegang is ingeschakeld wanneer de antivirusengine geopende bestanden probeert te scannen op virussen, door het in het geheugen laden van de volledige inhoud van elk bestand geopend door een ander proces.

Afhankelijk van uw beveiligingshouding en de noodzaak van deze overdracht, moet u het uitschakelen van ClamAV-scannen bij toegang evalueren terwijl u de overdracht uitvoert.


2
2017-09-28 10:34



Ik wist niet dat dit zelfs een ding was dat clamav kon doen ... maar nee we scannen alleen specifieke bestanden die er vanuit clamc naar toe zijn geleid. Ook 32-bits, dus geen gevaar dat het systeemgeheugen wordt geblokkeerd. (zie je waarom we dachten dat 32 bit nog steeds een goed idee was?) - dataless
De Linux-kernel meldt dat clamd het proces is waarvan de geheugentoewijzingsverzoeken de OOM-moordenaar oproepen - ClamAV is vrijwel zeker de secundaire oorzaak (de primaire oorzaak is niet genoeg geheugen). Of het nu gaat om scannen bij toegang of een andere configuratie, alle tekens wijzen naar ClamAV. - oo.
De volgende keer dat u de rsync start, voert u de top uit en controleert u de residente grootte van het clamd-proces. - oo.
clamd was het eerste proces om de oom moordenaar aan te roepen, maar ook de eerste om eraan te sterven omdat het weegt op bijna 42MB (een van de grotere processen op de server). De oom_killer loopt daarna herhaaldelijk tot zelfs metalog wordt gedood. - dataless