Frage Rsync löste Linux OOM Killer in einer einzigen 50-GB-Datei aus


Ich habe eine einzelne 50-GB-Datei auf Server_A, und ich kopiere es auf Server_B. ich renne

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

Server_B hat 32 GB RAM mit 2 GB Swap. Es ist meistens leer und sollte viel freien RAM haben. Es hat viel Speicherplatz. Bei ca. 32 GB bricht die Übertragung ab, weil die Remote-Seite die Verbindung geschlossen hat.

Server_B ist jetzt vom Netzwerk getrennt. Wir bitten das Rechenzentrum, es neu zu starten. Wenn ich das Kernel-Protokoll von vor dem Absturz anschaue, sehe ich, dass es 0 Byte Swap verwendet, und die Prozessliste verwendet sehr wenig Speicher (der rsync-Prozess wurde aufgelistet als 600 KB RAM zu verwenden), aber der oom_killer war gehen wild, und das letzte Ding im Protokoll ist, wo es metalogs Kernleseprozess tötet.

Das ist Kernel 3.2.59, 32-Bit (also kann kein Prozess mehr als 4 GB abbilden).

Es ist fast so, als hätte Linux Caching mehr Priorität eingeräumt als langlebigen Dämonen. Was gibt?? Und wie kann ich verhindern, dass es wieder passiert?

Hier ist die Ausgabe des 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 ist die 'top' Ausgabe nachdem ich meinen rsync Befehl als Nicht-root Benutzer wiederholt habe:

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

Hier sind die sysctl vm Parameter:

# 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


Ursprung


Ich bin kein Experte im Lesen von Kernel-Crash-Nachrichten, aber ich kann keinen Hinweis darauf finden, dass B 32 GB Core verwendet. Bevor wir davon ausgehen, dass es war, können Sie bestätigen, dass es derzeit ist? Denn es gibt einen großen Unterschied zwischen Speicher, der eine Box mit 32 GB Kern und einer mit nur 4 GB ausschöpft. - MadHatter
Mit Top-Ausgabe aktualisiert. Dies geschieht, nachdem derselbe rsync-Befehl als Nicht-root-Benutzer ausgeführt wurde. So ziemlich alles außer 1GB wird für den Cache verwendet. - dataless
Vielen Dank. Wie gesagt, ich bin kein Experte - aber es schien eine Überprüfung wert. - MadHatter
Sie sollten auch überprüfen, dass Ihr Kernel das Swapping erlaubt (dh das Swapping ist nicht ausgeschaltet) (und Sie sollten einen größeren Teil des Speicherplatzes reservieren, sagen wir 16 GB oder sogar 32 GB). Einige seltsame Personen im Netz empfehlen, das Swapping auszuschalten, was sehr falsch ist. - Olivier Dulac
@OlivierDulac auf welche Einstellung beziehen Sie sich? Die Swap-Unterstützung ist kompiliert, oder wir können Swap nicht mounten, und die 'Swappiness' ist auf 60 gesetzt. Würde die Swap-Größe das Problem auf einem 32-Bit-Kernel nicht noch schlimmer machen? Die Antwort scheint, dass Kernel-Datenstrukturen uns umgebracht haben. Wir haben keine 32GB User-Prozesse, wir wollen nur so viel RAM für den Festplatten-Cache, für die Leistung. - dataless


Antworten:


Lasst uns also die Oom-Killer-Ausgabe lesen und sehen, was daraus gelernt werden kann.

Bei der Analyse von OOM-Killerprotokollen ist es wichtig zu sehen, was sie ausgelöst hat. Die erste Zeile Ihres Logbuchs gibt uns einige Hinweise:

[Kernel] [1772321.850644] Clamd aufgerufen Oom-Killer: gfp_mask = 0x84d0, Reihenfolge = 0

order=0 sagt uns, wie viel Speicher angefordert wird. Die Speicherverwaltung des Kernels kann nur Seitenzahlen in den Potenzen von 2 verwalten, also hat clamd 2 angefordert0 Seiten mit Speicher oder 4KB.

Die untersten zwei Bits von GFP_MASK (freie Seitenmaske erhalten) bilden das sogenannte Zonenmaske  dem Zuordner mitteilen, aus welcher Zone der Speicher abgerufen werden soll:

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

Speicherzonen ist ein Konzept, das hauptsächlich aus Gründen der Kompatibilität erstellt wurde. In einer vereinfachten Ansicht gibt es drei Zonen für einen 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 Ihrem Fall ist die Zonemask 0, was bedeutet, dass clamd Speicher abfragt ZONE_NORMAL.

Die anderen Flags lösen auf

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

laut Linux MM Dokumentation, also hat dein reqst die flags für GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IO und GFP_WAITund somit nicht besonders wählerisch.

Also, was ist los? ZONE_NORMAL? Einige allgemeine Statistiken finden Sie weiter unten in der OOM-Ausgabe:

[Kernel] [1772321.850770] Normal frei: 8056kB min: 8048kB niedrig: 10060kB hoch: 12072kB active_anon: 0kB inaktive_anon: 0kB active_file: 248kB inaktive_datei: 388kB unlesbar: 0kB isoliert (anon)   : 0kB isoliert (Datei): 0kB vorhanden: 890008kB

Bemerkenswert hier ist das free ist nur 8 km von min und weit unter low. Dies bedeutet, dass der Speichermanager Ihres Hosts etwas in Bedrängnis ist und kswapd sollte Seiten bereits austauschen, wie es in der Gelb Phase der Grafik unten: Linux memory manager graph

Einige weitere Informationen zur Speicherfragmentierung der Zone finden Sie hier:

[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

im Grunde, dass Sie eine einzelne zusammenhängende Seite von 4 MB mit dem Rest stark in hauptsächlich 4 KB Seiten fragmentiert haben.

Also lassen Sie uns rekapitulieren:

  • Sie haben einen Userland-Prozess (clamd) Erinnerung bekommen ZONE_NORMAL während normalerweise eine nicht-privilegierte Speicherzuweisung durchgeführt wird ZONE_HIMEM
  • Der Speichermanager sollte zu diesem Zeitpunkt in der Lage sein, die angeforderte 4K-Seite zu bedienen, obwohl Sie einen erheblichen Speicherdruck zu haben scheinen ZONE_NORMAL
  • das System, durch kswapd's Regeln, sollte Ich habe vorher einige Paging - Aktivitäten gesehen, aber nichts wird ausgelagert, auch nicht unter dem Speicherdruck in ZONE_NORMALohne ersichtlichen Grund
  • Keines der obigen gibt einen bestimmten Grund dafür, warum oom-killer wurde aufgerufen

All dies scheint ziemlich merkwürdig zu sein, muss aber zumindest mit dem in Zusammenhang gebracht werden Abschnitt 2.5 von John O'Gormans exzellentem Buch "Understanding the Linux Virtual Memory Manager":

Da der vom Kernel verwendbare Adressraum (ZONE_NORMAL) in seiner Größe begrenzt ist, unterstützt der Kernel das Konzept des hohen Speichers. [...] Um auf Speicher zwischen dem Bereich von 1GiB und 4GiB zuzugreifen, bildet der Kernel temporär Seiten aus dem hohen Speicher mit kmap () in ZONE_NORMAL ab. [...]

Das bedeutet, dass zur Beschreibung von 1 GB Speicher etwa 11 MB Kernelspeicher erforderlich sind. Somit werden mit 16GiB 176MiB Speicher verbraucht, wodurch ZONE_NORMAL erheblich unter Druck gesetzt wird. Das hört sich nicht so schlecht an, bis andere Strukturen mit ZONE_NORMAL berücksichtigt werden. Selbst sehr kleine Strukturen wie Page Table Entries (PTEs) benötigen im schlimmsten Fall etwa 16MiB. Dies macht 16GiB über das praktische Limit für den verfügbaren physikalischen Speicher Linux auf einem x86.

(Schwerpunkt ist meiner)

Da 3.2 im Speichermanagement über 2.6 zahlreiche Fortschritte gemacht hat, ist dies keine eindeutige Antwort, sondern ein wirklich starker Hinweis, den ich zuerst verfolgen würde. Reduzieren Sie den nutzbaren Speicher des Hosts auf höchstens 16G, indem Sie entweder den mem= Kernel-Parameter oder durch Rippen der Hälfte der DIMMs aus dem Server.

Letzten Endes, Verwenden Sie einen 64-Bit-Kernel.

Alter, es ist 2015.


179
2017-09-24 10:46



Als ich oben sagte "Ich bin kein Experte", diese habe ich gehofft zu lesen. +1000, wenn ich aber könnte; +1 für sicher. Was für eine großartige Antwort! - MadHatter
Das war schön. Es gibt immer noch Hoffnung für SF. - Roman
@dateless Ja. Ich vermute, dass all Ihre ZONE_NORMAL mit Metadaten über die oberen Speicherbereiche gefüllt ist. Wenn ein Userland-Prozess Speicherseiten anfordert, wird höchstwahrscheinlich ZONE_HIGHMEM angefordert (das von der MM auf ZONE_NORMAL aktualisiert werden kann, wenn HIGHMEM keine freien Seiten mehr zur Verfügung hat, die NORMAL hat), es sei denn, ZONE_HIGHMEM befindet sich unter Speicherdruck (deins ist nicht), ZONE_NORMAL wird keine User-Space-Prozesse Seiten haben. - the-wabbit
[schlägt Fäuste auf der Tastatur] Geben Sie diesem Wabbit das Kopfgeld - underscore_d
@ the-wabbit Hot Netzwerk Fragen. - CodesInChaos


Ein paar Dinge ...

Meine Faustregel für Swap Space war, mindestens die doppelte Menge an physischem RAM zu haben. Dies ermöglicht dem Seiten- / Auslagerungsdämon die effiziente Speichererweiterung.

Server_B hat 32 GB RAM, also versuche es für 64 GB Swap zu konfigurieren. IMO, der 2GB Swap Space, den Ihr Server hat Weg zu niedrig, besonders für einen Server.

Wenn Sie keine extra Partition haben, die Sie zu einer Swap-Partition machen können, können Sie dies testen, indem Sie eine Datei erstellen und sie als Swap-Partition mounten [es wird langsam]. Sehen https://www.maketecheasier.com/swap-partitions-on-linux/

Da server_B über ausreichend Speicherplatz verfügt, wird --inplace nicht benötigt und ist möglicherweise unerwünscht, da rsync möglicherweise 32GB benötigt. --inplace ist nur dann wirklich nützlich, wenn Sie wenig Platz auf dem Dateisystem haben (was Sie nicht sind) oder spezielle Leistungsanforderungen haben.

Meine Vermutung ist, dass rsync 50 GB RAM [die Dateigröße] mit Ihren aktuellen Optionen verwenden möchte. Normalerweise benötigt rsync nicht so viel Arbeitsspeicher, um seine Aufgabe zu erledigen. Daher können eine oder mehrere Optionen das Problem sein. Ich übertrage regelmäßig 200 GB Dateien ohne Probleme.

Führen Sie einige Testläufe ohne Optionen durch. Tun Sie dies mit kleineren Dateien, sagen wir 10GB - das sollte die Kernel-Panic verhindern, aber Sie können immer noch das Verhalten überwachen, das das Problem verursacht. Überwachen Sie die Speicherbelegung von rsync.

Nach und nach fügen Sie Optionen nacheinander hinzu, um zu sehen, welche Option [oder Kombination von Optionen] bewirkt, dass rsync mit dem RAM im RAM beginnt (z. B. während der Übertragung wächst rsync's RAM-Auslastung proportional zur übertragenen Dateimenge.) usw.).

Wenn Sie wirklich die Optionen benötigen, die rsync dazu veranlassen, einige In-Ram-Datei-Images zu behalten, benötigen Sie zusätzlichen Swap-Speicherplatz und Ihre maximale Dateigröße wird entsprechend begrenzt.

Ein paar mehr Dinge [UPDATED]:

(1) Die Rückverfolgung des Kernel-Stacks zeigt, dass rsync Seitenfehler in einem mmap-Bereich verursacht hat. Es ist wahrscheinlich die Datei mmaping. mmap bietet keine Garantie, dass es auf die Festplatte spült bis um die Datei ist geschlossen [im Gegensatz zu Lesen / Schreiben], die sofort zum FS-Blockcache führt [wo sie gelöscht wird]

(2) Der Kernel-Crash / Panic tritt auf, wenn die Übertragungsgröße die Größe von RAM erreicht. Klar, dass rsync so viel Nicht-fscache-Speicher über malloc oder mmap ergreift. Mit den von Ihnen angegebenen Optionen weist rsync für die Übertragung einer 50-GB-Datei 50 GB Arbeitsspeicher zu.

(3) Übertragen Sie eine 24-GB-Datei. Das wird wahrscheinlich funktionieren. Dann booten Sie den Kernel mit mem = 16G und führen Sie den 24GB Dateitest erneut durch. Es wird bei 16 GB statt 32 GB ausblasen. Dies bestätigt, dass rsync den Speicher wirklich benötigt.

(4) Bevor Sie sagen, dass das Hinzufügen von Swap lächerlich ist, versuchen Sie einige [über die Swap-to-File-Methode] hinzuzufügen. Dies ist viel einfacher zu tun und zu testen als alle akademischen Argumente darüber, wie Swap nicht erforderlich ist. Auch wenn es nicht die Lösung ist, können Sie daraus etwas lernen. Ich wette, dass mem = 16G Test ohne Panik / Absturz erfolgreich sein wird.

(5) Chancen sind, dass rsync ist swap, aber es passiert zu schnell, um mit top zu sehen, bevor OOM startet und rsync beendet. Zu dem Zeitpunkt, zu dem Rsync 32 GB erreicht, wurden andere Prozesse bereits zum Austauschen gezwungen, insbesondere wenn sie im Leerlauf sind. Vielleicht wird Ihnen eine Kombination aus "frei" und "top" ein besseres Bild geben.

(6) Nachdem rsync beendet wurde, benötigt es Zeit, um mmap zum FS zu spülen. Nicht schnell genug für OOM und es beginnt andere Dinge zu töten [einige sind offensichtlich unternehmenskritisch]. Das heißt, die mmap flush und OOM sind Rennsport. Oder, OOM hat einen Fehler. Sonst würde es keinen Absturz geben.

(7) Nach meiner Erfahrung benötigt Linux, wenn ein System einmal die Speicherwand erreicht hat, eine lange Zeit, bis es vollständig wiederhergestellt ist. Und manchmal wird es nie richtig wiederhergestellt und der einzige Weg, es zu löschen, ist ein Neustart. Zum Beispiel habe ich 12 GB RAM. Wenn ich einen Job ausführe, der 40 GB Arbeitsspeicher verwendet [ich habe 120 GB Swap, um große Jobs zu verarbeiten] und ihn dann abbricht, dauert es etwa 10 Minuten, bis das System wieder normal reagiert [wobei die Festplattenanzeige ständig leuchtet] .

(8) Führen Sie rsync aus ohne Optionen. Das wird funktionieren. Erhalte ein Basisbeispiel, von dem aus gearbeitet werden kann. Fügen Sie dann --inplace zurück und testen Sie erneut. Führen Sie dann --append-verify statt. Dann versuche beides. Finden Sie heraus, welche Option rsync die riesige mmap tut. Dann entscheiden Sie, ob Sie ohne es leben können. Wenn --inplace ist der Schuldige, das ist ein Kinderspiel, da Sie viel Speicherplatz haben. Wenn Sie die Option haben müssen, müssen Sie den Swap-Space abrufen, um die malloc / mmap, die rsync tun wird, unterzubringen.

ZWEITES UPDATE:

Bitte machen Sie die mem = und kleinere Dateitests von oben.

Die zentralen Fragen: Warum wird rsync von OOM getötet? Wer / Was ist Kaugedächtnis?

Ich habe [aber vergessen], dass das System 32 bit ist. Daher stimme ich zu, dass rsync möglicherweise nicht direkt verantwortlich ist (via malloc / mmap - glibc implementiert große mallocs über anonyme / private mmaps), und rsyncs mmap-Seitenfehler löst zufälligerweise nur OOM aus. Dann berechnet OOM den gesamten von rsync verbrauchten Speicher direkt und indirekt [FS-Cache, Socket-Puffer usw.] und entscheidet, dass es der Hauptkandidat ist. Daher kann die Überwachung der Gesamtspeicherauslastung hilfreich sein. Ich vermute, dass es mit der gleichen Rate wie die Dateiübertragung schleicht. Offensichtlich sollte es nicht.

Einige Dinge, die Sie in / proc oder / proc / rsync_pid über ein Perl- oder Python-Skript in einer schnellen Schleife überwachen können [ein Bash-Skript ist wahrscheinlich nicht schnell genug für das Ende der Welt-Ereignis], das alle überwachen kann die folgenden mehrere hundert mal / sek. Sie können dies mit einer höheren Priorität als rsync ausführen, so dass es sich im RAM befindet und läuft, so dass Sie die Dinge kurz vor dem Absturz überwachen können und hoffentlich während OOM, damit Sie sehen können, warum OOM verrückt spielt:

/ proc / meminfo - um mehr Feinkorn auf die Swap-Nutzung am "Point of Impact" zu bekommen. Tatsächlich kann es nützlich sein, die endgültige Anzahl der insgesamt genutzten RAM zu erhalten. Während top dies bietet, ist es möglicherweise nicht schnell genug, um den Zustand des Universums kurz vor dem "Big Bang" (z. B. die letzten 10 Millisekunden) anzuzeigen.

Verzeichnis / proc / rsync_pid / fd. Durch das Lesen der Symlinks können Sie feststellen, welches fd in der Zieldatei geöffnet ist (z. B. readlink von / proc / rsync_pid / fd / 5 -> target_file). Dies muss wahrscheinlich nur einmal gemacht werden, um die fd-Nummer zu bekommen [es sollte fest bleiben]

Wenn Sie die fd-Nummer kennen, sehen Sie sich / proc / rsync_pid / fdinfo / fd an. Es ist eine Textdatei, die wie folgt aussieht:

pos: <Dateiposition>
Flaggen: blah_blah
mnt_id: blah_blah

Die Überwachung des "pos" -Wertes kann hilfreich sein, da die "letzte Dateiposition" nützlich sein kann. Wenn Sie mehrere Tests mit unterschiedlichen Größen und mem = Optionen durchführen, verfolgt die letzte Dateiposition einen dieser [und wie]? Der übliche Verdächtige: Dateiposition == verfügbarer RAM

Aber am einfachsten ist es, mit "rsync local_file server: remote_file" zu beginnen und zu überprüfen, ob das funktioniert. Sie können ähnliche [aber schnellere] Ergebnisse erzielen, indem Sie "ssh server rsync file_a file_b" ausführen [Sie müssten zuerst eine 50GB-Datei erstellen_a]. Eine einfache Möglichkeit, um file_a zu erstellen, ist scp local_system: original_file server: file_a und das könnte für sich interessant sein (funktioniert das zB, wenn rsync abstürzt? Wenn scp funktioniert, aber rsync fehlschlägt, zeigt dies auf rsync. Wenn scp fehlschlägt, zeigt dies zu etwas anderem wie dem NIC-Treiber). Durch die Verwendung von ssh rsync wird die NIC ebenfalls aus der Gleichung entfernt, was hilfreich sein kann. Wenn das System schlaucht, dann stimmt etwas wirklich nicht. Wenn es gelingt, [wie ich bereits erwähnt habe], fügen Sie die Optionen nacheinander hinzu.

Ich hasse es, den Punkt zu belasten, aber das Hinzufügen von etwas Swap über Swap-to-File kann das Absturzverhalten verändern / verzögern und kann als Diagnosewerkzeug nützlich sein. Wenn das Hinzufügen von beispielsweise 16 GB Swap den Absturz [von der Speicherbelegung oder der Zieldateiposition gemessen] von 32 GB auf 46 GB verzögert, dann wird das etwas sagen.

Möglicherweise handelt es sich nicht um einen bestimmten Prozess, sondern um einen fehlerhaften Kernel-Treiber, der Speicher kaut. Das interne vmalloc des Kernels weist Sachen zu und es kann ausgetauscht werden. IIRC, es ist nicht unter allen Umständen an die Adressierbarkeit gebunden.

Offensichtlich wird das OOM verwirrt / panisch. Das heißt, es tötet rsync, aber sieht den Speicher nicht rechtzeitig frei und sucht nach anderen Opfern. Einige von ihnen sind wahrscheinlich kritisch für den Systembetrieb.

malloc / mmap beiseite, könnte dies durch unflushed FS-Cache verursacht werden, die eine lange Zeit dauert (z. B. mit 30 GB unflushed Daten, eine Plattenrate von 300 MB / s vorausgesetzt, kann es 100 Sekunden dauern, um es zu fluten). Selbst bei dieser Geschwindigkeit kann OOM zu ungeduldig sein. Oder, OOM Rsync zu töten startet die FS-Flush nicht schnell genug [oder überhaupt]. Oder FS-Flush geschieht schnell genug, aber es hat eine "faule" Freigabe der Seiten zurück in den freien Pool. Es gibt einige / proc-Optionen, die Sie einstellen können, um das FS-Cache-Verhalten zu steuern [ich kann mich nicht erinnern, was sie sind].

Versuchen Sie, mit mem = 4G oder einer anderen kleinen Zahl zu booten. Dies könnte den FS-Cache einschränken und seine Löschzeit verkürzen, damit OOM nicht nach anderen Dingen suchen muss, die es zu töten gilt (z. B. wird die Löschzeit von 100 auf <1 Sekunde verringert). Es kann auch einen OOM-Fehler demaskieren, der physischen RAM> 4 GB auf einem 32-Bit-System oder ähnlichem nicht verarbeiten kann.

Ein weiterer wichtiger Punkt: Als nicht root ausführen. Von Root-Benutzern wird nie erwartet, dass sie Ressourcen kauen, daher erhalten sie mehr verzeihende Grenzen (z. B. 99% des Speichers gegenüber 95% für Nicht-Root-Benutzer). Dies könnte erklären, warum OOM in einem solchen Zustand ist. Auch dies gibt OOM et. al. mehr Spielraum für die Wiederherstellung der Erinnerung.


4
2017-09-27 20:30



Sehen Wie viel SWAP-Speicherplatz in einem Hochspeichersystem? - und Sie möchten nicht, dass Ihr System 63 GB Swap verwendet. Es wird nicht verwendbar sein. - Martin Schröder
swap> RAM ist nur dann wirklich nützlich, wenn Sie ohne VM-Overcommit laufen, also muss der Kernel Swap-Space für die zugewiesenen Seiten reservieren, bis sie verschmutzt sind und echte physische Seiten benötigen, die sie unterstützen. Derzeitige Praxis besteht darin, eine Überbelegung zuzulassen und mit einer kleinen Menge an Auslagerungsspeicher auszugeben, um Seiten auszugeben, die beim Start nur berührt wurden und im normalen Betrieb nicht benötigt werden. Overcommit = 0 mit kleinem Swap ist in Ordnung, wenn Sie viel RAM haben, für die meisten Systeme. - Peter Cordes
Es scheint, dass rsync wirklich ist versuche> 32GB zu verwenden, also wird der Swap dafür benötigt. Das heißt, rsync wird 50 GB für diese Datei verwenden. Das 2x ist seit 30 Jahren eine bewährte Metrik. Da eine 6TB Festplatte ~ 300 $ ist, gibt es keinen Grund, dies nicht zu tun. Was sonst könnte auf diesem Server laufen, der zusammen das RAM-Limit überschreiten wird? - Craig Estey
@CraigEstey 64 GB Swap ist vollkommen lächerlich, da wir, wie ich bereits erwähnt habe, keine großen Benutzerprozesse haben. Wir wollen nur den Plattencache, und wie mein Protokoll zeigte, benutzten wir zum Zeitpunkt des Absturzes ZERO Swap. NULL. Auch rsync verwendet 600 KB RAM sogar auf einer 50 GB-Datei. Meine anfängliche Verwirrung war, dass vielleicht Linux den Plattencache aggressiv festhielt. Und schließlich möchte ich einige Zahlen oder eine Dokumentation darüber sehen, wie viel Speicher der Kernel verwendet, um seinen Auslagerungsspeicher zu verfolgen, bevor ich noch mehr zu dieser Box hinzufügen würde. - dataless
@dataless Ich habe zusätzliche Informationen hinzugefügt, die vollständig erklären, was passiert und warum. rsync ist greifen Sie den Speicher über Malloc / mmap und es wird für 50 GB gehen, bevor es fertig ist. Siehe den aktualisierten Abschnitt. Es hat Tests, die beweisen / widerlegen können, was ich sage, und Sie können den hinzugefügten Swap zuerst überspringen, um zu testen. BTW, ich habe seit über 40 Jahren Kernel / Treiber programmiert - ich könnte vielleicht etwas wissen, was du nicht tust, also bitte moderiere den Ton - ich bin versuchen zu helfen. - Craig Estey


Clamd? Es klingt, als ob Sie ClamAV verwenden und On-Access-Scans aktiviert haben, bei denen die Antiviren-Engine versucht, geöffnete Dateien auf Viren zu prüfen. indem der gesamte Inhalt jeder Datei, die von einem anderen Prozess geöffnet wurde, in den Speicher geladen wird.

Abhängig von Ihrer Sicherheitseinstellung und der Notwendigkeit dieser Übertragung sollten Sie die Deaktivierung von ClamAV On-Access-Scans während der Übertragung evaluieren.


2
2017-09-28 10:34



Ich war mir nicht bewusst, dass dies überhaupt etwas war, was Clamav tun konnte ... aber wir scannen nur bestimmte Dateien, die von clcmc an es weitergeleitet wurden. Auch 32-Bit, also keine Gefahr von clamav den gesamten Systemspeicher hogging. (Sie sehen, warum wir dachten 32-Bit war immer noch eine gute Idee?) - dataless
Der Linux-Kernel wird berichtet, dass clamd der Prozess, dessen Speicherzuordnungsanforderungen werden den Aufruf des OOM Killer - ClamAV ist mit ziemlicher Sicherheit die sekundäre Ursache (die primäre Ursache ist nicht genug Speicher). Ob es sich um On-Access-Scans oder andere Konfigurationen handelt, alle Anzeichen deuten auf ClamAV hin. - oo.
Wenn Sie das rsync das nächste Mal starten, führen Sie top aus und überwachen Sie die resident-Größe des Clamd-Prozesses. - oo.
Clamd war der erste Prozess, der den Oom-Killer aufrief, aber auch der Erste, der daran starb, da er fast 42 MB (einen der größeren Prozesse auf dem Server) wiegt. Der oom_killer wird danach wiederholt ausgeführt, bis sogar Metalog getötet wird. - dataless