Rsync memicu Linux OOM killer pada satu file 50 GB


66

Saya punya satu file 50 GB di server_A, dan saya menyalinnya ke server_B. saya berlari

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

Server_B memiliki 32 GB RAM dengan 2 GB swap. Sebagian besar tidak digunakan dan seharusnya memiliki banyak RAM gratis. Ini memiliki banyak ruang disk. Pada sekitar 32 GB, transfer dibatalkan karena sisi jarak jauh menutup koneksi.

Server_B sekarang telah meninggalkan jaringan. Kami meminta pusat data untuk reboot. Ketika saya melihat log kernel dari sebelum crash, saya melihat bahwa itu menggunakan 0 byte swap, dan daftar proses menggunakan memori sangat sedikit (proses rsync terdaftar menggunakan 600 KB RAM), tetapi oom_killer adalah menjadi liar, dan hal terakhir dalam log adalah di mana ia membunuh proses pembaca kernel metalog.

Ini adalah kernel 3.2.59, 32-bit (jadi tidak ada proses yang dapat memetakan lebih dari 4 GB).

Ini hampir seolah-olah Linux memberikan prioritas lebih untuk caching daripada daemon berjalan lama. Apa yang memberi ?? Dan bagaimana saya bisa menghentikannya agar tidak terjadi lagi?

Ini adalah output dari 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

Ini adalah output 'top' setelah mengulangi perintah rsync saya sebagai pengguna 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

Berikut adalah parameter 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

2
Saya bukan ahli dalam membaca pesan crash kernel, tapi saya tidak bisa melihat indikasi di sana bahwa B menggunakan 32GB inti. Sebelum kami melanjutkan dengan asumsi itu, bisakah Anda mengonfirmasi bahwa itu saat ini? Karena ada perbedaan besar antara kehabisan memori kotak dengan 32GB inti, dan satu dengan hanya 4GB.
MadHatter

Diperbarui dengan Top output. Ini setelah menjalankan perintah rsync yang sama sebagai pengguna non-root. Hampir semua kecuali 1GB digunakan untuk cache sekarang.
dataless

Terima kasih. Seperti yang saya katakan, saya bukan ahli - tetapi sepertinya layak untuk diperiksa.
MadHatter

Anda juga harus memverifikasi bahwa kernel Anda mengizinkan swapping (yaitu, swapping tidak dimatikan) (dan Anda harus mendedikasikan ruang disk yang lebih besar, misalkan 16Gb atau bahkan 32Gb). Beberapa orang aneh di internet merekomendasikan untuk bertukar, yang sangat salah.
Olivier Dulac

@OlivierDulac pengaturan apa yang Anda maksud? dukungan swap dikompilasi dalam atau kita tidak akan bisa me-mount swap, dan 'swappiness' diatur ke 60. Adapun ukuran swap, bukankah itu hanya membuat masalah lebih buruk, pada kernel 32-bit? Jawabannya muncul bahwa struktur data kernel adalah yang membunuh kita. Kami tidak menjalankan proses pengguna 32GB, kami hanya menginginkan ram yang banyak untuk cache disk, untuk kinerja.
dataless

Jawaban:


178

Jadi mari kita baca hasil oom-killer dan lihat apa yang bisa dipelajari dari sana.

Saat menganalisis log pembunuh OOM, penting untuk melihat apa yang memicu itu. Baris pertama log Anda memberi kami beberapa petunjuk:

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

order=0memberitahu kami berapa banyak memori yang diminta. Manajemen memori kernel hanya dapat mengatur nomor halaman dengan kekuatan 2, sehingga clamd telah meminta 2 0 halaman memori atau 4KB.

Dua bit terendah dari GFP_MASK (dapatkan mask halaman gratis) merupakan yang disebut mask zona memberi tahu pengalokasi zona mana untuk mendapatkan memori dari :

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

Zona memori adalah konsep yang dibuat terutama untuk alasan kompatibilitas. Dalam tampilan yang disederhanakan, ada tiga zona untuk kernel 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

Dalam kasus Anda, zonemask adalah 0, artinya clamd meminta memori dari ZONE_NORMAL.

Bendera lainnya sedang diperbaiki

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

menurut dokumentasi Linux MM , sehingga requst Anda memiliki bendera untuk GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOdan GFP_WAIT, dengan demikian menjadi tidak terlalu pilih-pilih.

Jadi ada apa ZONE_NORMAL? Beberapa statistik umum dapat ditemukan lebih jauh di dalam output OOM:

[kernel] [1772321.850770] Normal gratis: 8056kB min: rendah 8048kB: tinggi 10060kB : 12072kB aktif_anon: 0kB tidak aktif_anon: 0kB aktif_file: 248kB tidak aktif_file: 388kB tidak dapat dihapus: 0kB terisolasi (anon): 0000 fileB: file)

Yang terlihat di sini adalah freehanya 8K dari mindan jauh di bawah low. Ini berarti manajer memori host Anda agak tertekan dan kswapd harus sudah menukar halaman dengan fase kuning dari grafik di bawah ini: Grafik manajer memori Linux

Beberapa informasi lebih lanjut tentang fragmentasi memori zona diberikan di sini:

[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 * 4048kB 1 * 4096kB = 8056kB =

pada dasarnya menyatakan bahwa Anda memiliki satu halaman bersebelahan 4MB dengan sisanya sangat terfragmentasi menjadi halaman 4KB.

Jadi mari kita rekapitulasi:

  • Anda memiliki proses userland ( clamd) mendapatkan memori dari mana ZONE_NORMALalokasi memori non-istimewa biasanya akan dilakukan dariZONE_HIMEM
  • manajer memori pada tahap ini seharusnya dapat melayani halaman 4K yang diminta, meskipun Anda tampaknya memiliki tekanan memori yang signifikan ZONE_NORMAL
  • sistem, dengan kswapdaturan, seharusnya melihat beberapa aktivitas paging sebelumnya, tetapi tidak ada yang ditukar, bahkan di bawah tekanan memori ZONE_NORMAL, tanpa sebab yang jelas
  • Tidak satu pun di atas memberikan alasan yang pasti mengapa oom-killertelah dipanggil

Semua ini tampaknya agak aneh, tetapi setidaknya terkait dengan apa yang dijelaskan dalam bagian 2.5 buku John O'Gorman yang sangat baik "Memahami Linux Virtual Memory Manager" :

Karena ruang alamat yang dapat digunakan oleh kernel (ZONE_NORMAL) dalam ukuran terbatas, kernel memiliki dukungan untuk konsep Memori Tinggi. [...] Untuk mengakses memori antara kisaran 1GiB dan 4GiB, kernel sementara memetakan halaman dari memori tinggi ke ZONE_NORMAL dengan kmap (). [...]

Itu berarti untuk menggambarkan memori 1GiB, diperlukan sekitar 11MiB memori kernel. Dengan demikian, dengan 16GiB, memori 176MiB dikonsumsi, memberikan tekanan signifikan pada ZONE_NORMAL. Ini tidak terdengar terlalu buruk sampai struktur lain diperhitungkan yang menggunakan ZONE_NORMAL. Bahkan struktur yang sangat kecil seperti Entri Table Page (PTEs) membutuhkan sekitar 16MiB dalam kasus terburuk. Ini membuat 16GiB tentang batas praktis untuk memori fisik Linux yang tersedia pada x86 .

(Penekanan adalah milikku)

Karena 3.2 memiliki banyak kemajuan dalam manajemen memori lebih dari 2,6, ini bukan jawaban yang pasti, tetapi petunjuk yang sangat kuat saya akan mengejar dulu. Kurangi memori host yang dapat digunakan paling banyak 16G baik dengan menggunakan mem=parameter kernel atau dengan merobek setengah DIMM keluar dari server.

Pada akhirnya, gunakan Kernel 64-bit .

Bung, ini tahun 2015.


13
Ketika saya mengatakan di atas, " Saya bukan ahli ", inilah yang ingin saya baca. +1000, jika saya tetapi bisa; +1 pasti. Jawaban yang bagus!
MadHatter

18
Itu indah. Masih ada harapan untuk SF.
Roman

9
@ kematian Ya. Saya menduga bahwa semua ZONE_NORMAL Anda diisi dengan metadata tentang wilayah memori atas. Ketika proses userland meminta halaman memori, kemungkinan besar akan meminta ZONE_HIGHMEM (yang mungkin ditingkatkan oleh MM ke ZONE_NORMAL jika HIGHMEM tidak memiliki lagi halaman gratis untuk melayani permintaan tetapi NORMAL memiliki), jadi kecuali ZONE_HIGHMEM berada di bawah tekanan memori (milik Anda tidak), ZONE_NORMAL tidak akan memiliki halaman proses ruang pengguna.
the-wabbit

3
[membanting tinju di keyboard] Berikan hadiah ini wabbit
underscore_d

3
@ the-wabbit Pertanyaan jaringan panas.
CodesInChaos

4

Beberapa hal ...

Aturan praktis saya untuk ruang swap adalah memiliki setidaknya 2 x jumlah ram fisik. Hal ini memungkinkan halaman / swap daemon kemampuan untuk menyusun kembali memori secara efisien.

Server_B memiliki 32GB ram, jadi coba konfigurasikan untuk 64GB swap. IMO, 2GB ruang swap server Anda memiliki adalah cara terlalu rendah, terutama untuk server.

Jika Anda tidak memiliki partisi tambahan yang dapat Anda buat menjadi partisi swap, Anda dapat mengujinya dengan membuat file dan memasangnya sebagai partisi swap [akan lambat]. Lihat https://www.maketecheasier.com/swap-partitions-on-linux/

Karena server_B memiliki banyak ruang disk, --di tempat tidak diperlukan, dan mungkin tidak diinginkan karena mungkin itulah yang menyebabkan rsync menggunakan 32GB. --inplace hanya sangat berguna jika Anda kekurangan ruang sistem file [yang tidak] atau memiliki persyaratan kinerja khusus.

Dugaan saya adalah bahwa rsync ingin menggunakan ram 50GB [ukuran file] dengan opsi Anda saat ini. Biasanya, rsync tidak membutuhkan banyak memori untuk melakukan tugasnya, jadi satu atau lebih opsi Anda mungkin menjadi masalah. Saya secara rutin mentransfer file 200GB tanpa masalah.

Lakukan beberapa pengujian tanpa menggunakan opsi. Lakukan ini dengan file yang lebih kecil, katakanlah 10GB - ini seharusnya mencegah kepanikan kernel, tetapi masih memungkinkan Anda untuk memantau perilaku yang menyebabkan masalah. Monitor penggunaan memori rsync.

Secara bertahap, tambahkan opsi kembali, satu per satu, untuk melihat opsi [atau kombinasi opsi] apa yang menyebabkan rsync mulai mengosongkan RAM (misalnya saat transfer sedang berlangsung, penggunaan ram rsync tumbuh secara proporsional dengan jumlah data file yang ditransfer, dll.)

Jika Anda benar-benar membutuhkan opsi yang menyebabkan rsync menyimpan beberapa file file in-ram, Anda akan memerlukan ruang swap tambahan dan ukuran file maksimum Anda akan dibatasi.

Beberapa hal lagi [DIPERBARUI]:

(1) Traceback stack kernel menunjukkan bahwa rsync adalah kesalahan halaman pada area mmap. Mungkin mmaping file. mmap tidak memberikan jaminan bahwa ia akan mem-flush ke disk sampai file ditutup [tidak seperti baca / tulis] yang langsung menuju ke cache blok FS [di mana ia akan disiram]

(2) Krisis / panik kernel terjadi ketika ukuran transfer mencapai ukuran RAM. Jelas rsync mengambil banyak memori non-fscache melalui malloc atau mmap. Sekali lagi, dengan opsi yang Anda tentukan, rsync akan mengalokasikan 50GB memori untuk mentransfer file 50GB.

(3) Transfer file 24GB. Itu mungkin akan berhasil. Kemudian, boot kernel dengan mem = 16G dan lakukan pengujian file 24GB lagi. Ini akan meledak pada 16GB daripada 32GB. Ini akan mengkonfirmasi bahwa rsync benar-benar membutuhkan memori.

(4) Sebelum Anda mengatakan bahwa menambahkan swap itu konyol, coba tambahkan beberapa [melalui metode swap-to-file]. Ini jauh lebih mudah dilakukan dan diuji daripada semua argumen akademis tentang bagaimana swap tidak diperlukan. Bahkan jika itu bukan solusinya, Anda dapat belajar sesuatu darinya. Saya berani bertaruh bahwa tes mem = 16G akan berhasil tanpa panik / crash.

(5) Kemungkinannya adalah bahwa rsync adalah memukul swap, tapi itu terjadi terlalu cepat untuk melihat dengan top sebelum tendangan OOM dan membunuh rsync. Pada saat rsync mencapai 32GB, proses lain telah dipaksa keluar untuk bertukar, terutama jika mereka menganggur. Mungkin, kombinasi "gratis" dan "atas" akan memberi Anda gambaran yang lebih baik.

(6) Setelah rsync terbunuh, perlu waktu untuk menyiram mmap ke FS. Tidak cukup cepat untuk OOM dan itu mulai membunuh hal-hal lain [beberapa di antaranya jelas kritis terhadap misi]. Artinya, mmap flush dan OOM sedang berpacu. Atau, OOM memiliki bug. Kalau tidak, tidak akan ada crash.

(7) Dalam pengalaman saya, sekali sistem "menyentuh dinding memori", Linux membutuhkan waktu lama untuk sepenuhnya pulih. Dan, kadang-kadang itu tidak pernah benar-benar pulih dengan baik dan satu-satunya cara untuk menghapusnya adalah reboot. Sebagai contoh, saya memiliki RAM 12GB. Ketika saya menjalankan pekerjaan yang menggunakan memori 40GB [saya memiliki 120GB swap untuk mengakomodasi pekerjaan besar] dan kemudian membunuhnya, dibutuhkan sekitar 10 menit bagi sistem untuk kembali ke respons normal [dengan lampu disk menyala solid sementara itu] .

(8) Jalankan rsync tanpa opsi. Ini akan bekerja Dapatkan contoh baseline untuk bekerja. Kemudian tambahkan kembali --di tempat dan uji ulang. Kemudian lakukan --append-verifikasi saja. Lalu, cobalah keduanya. Cari tahu opsi mana yang mendapatkan rsync melakukan mmap besar. Kemudian putuskan apakah Anda bisa hidup tanpanya. Jika --inplace adalah pelakunya, itu tidak perlu dipikirkan, karena Anda memiliki banyak ruang disk. Jika Anda harus memiliki opsi, Anda harus mendapatkan ruang swap untuk mengakomodasi malloc / mmap yang akan dilakukan rsync.

PEMBARUAN KEDUA:

Silakan lakukan mem = dan tes file yang lebih kecil dari yang di atas.

Pertanyaan sentral: Mengapa rsync terbunuh oleh OOM? Siapa / Apa itu mengunyah memori?

Saya membaca [tetapi lupa] tentang sistem menjadi 32 bit. Jadi, saya setuju, rsync mungkin tidak bertanggung jawab secara langsung (melalui malloc / mmap - glibc mengimplementasikan mallocs besar melalui mmaps anonim / pribadi), dan kesalahan halaman mms rsync hanya memicu OOM secara kebetulan. Kemudian, OOM menghitung total memori yang dikonsumsi oleh rsync secara langsung dan tidak langsung [cache FS, buffer socket, dll] dan memutuskan itu adalah kandidat utama. Jadi, memantau penggunaan memori total mungkin bermanfaat. Saya menduga itu merayap pada kecepatan yang sama dengan transfer file. Jelas, seharusnya tidak.

Beberapa hal yang dapat Anda monitor di / proc atau / proc / rsync_pid melalui skrip perl atau python dalam loop cepat [skrip bash mungkin tidak akan cukup cepat untuk acara akhir dunia] yang dapat memonitor semua berikut beberapa ratus kali / detik. Anda dapat menjalankan ini pada prioritas yang lebih tinggi daripada rsync sehingga ini akan tetap berjalan dalam RAM dan berjalan sehingga Anda dapat memantau hal-hal sebelum kecelakaan dan mudah-mudahan selama OOM sehingga Anda dapat melihat mengapa OOM menjadi gila:

/ proc / meminfo - untuk mendapatkan lebih banyak butiran halus pada penggunaan swap di "titik dampak". Sebenarnya, mendapatkan angka terakhir tentang berapa banyak RAM yang digunakan total mungkin lebih bermanfaat. Sementara top menyediakan ini, mungkin tidak cukup cepat untuk menunjukkan keadaan alam semesta sebelum "big bang" (mis. 10 milidetik terakhir)

direktori / proc / rsync_pid / fd. Membaca symlink akan memungkinkan Anda untuk mengidentifikasi fd mana yang dibuka pada file target (mis. Readlink dari / proc / rsync_pid / fd / 5 -> target_file). Ini mungkin hanya perlu dilakukan sekali untuk mendapatkan nomor fd [harus tetap diperbaiki]

Mengetahui nomor fd, lihat / proc / rsync_pid / fdinfo / fd. Ini adalah file teks yang terlihat seperti:

pos: <file_position>
bendera: blah_blah
mnt_id: blah_blah

Memantau nilai "pos" dapat membantu karena "posisi file terakhir" mungkin bermanfaat. Jika Anda melakukan beberapa tes dengan berbagai ukuran dan opsi mem =, apakah posisi file terakhir melacak semua ini [dan bagaimana]? Tersangka yang biasa: posisi file == RAM yang tersedia

Tetapi, cara paling sederhana adalah mulai dengan "rsync local_file server: remote_file" dan verifikasi yang berfungsi. Anda mungkin bisa mendapatkan hasil yang serupa [tetapi lebih cepat] dengan melakukan "ssh server rsync file_a file_b" [Anda harus membuat file_a 50GB terlebih dahulu]. Cara sederhana untuk membuat file_a adalah scp local_system: original_file server: file_a dan ini mungkin menarik bagi dirinya sendiri (misalnya apakah ini bekerja ketika rsync crash? Jika scp bekerja, tetapi rsync gagal, ini menunjuk ke rsync. Jika scp gagal, poin ini untuk sesuatu yang lain seperti driver NIC). Melakukan ssh rsync juga menghilangkan NIC dari persamaan, yang mungkin membantu. Jika itu menyirami sistem, maka ada sesuatu yang benar-benar salah. Jika berhasil, [seperti yang saya sebutkan] mulai menambahkan kembali opsi satu per satu.

Saya benci untuk mengulangi intinya, tetapi menambahkan beberapa swap melalui swap-to-file dapat mengubah / menunda perilaku crash dan mungkin berguna sebagai alat diagnostik. Jika menambahkan, katakanlah 16GB, swap menunda crash [yang diukur dengan penggunaan memori atau posisi file target] dari 32GB ke 46GB, maka itu akan mengatakan sesuatu.

Ini mungkin bukan proses tertentu, tetapi driver kernel yang salah yang mengunyah memori. Vmalloc internal kernel mengalokasikan hal-hal dan dapat ditukar. IIRC, itu tidak terikat oleh addressibility dalam segala keadaan.

Jelas, OOM semakin bingung / panik. Yaitu, itu membunuh rsync, tetapi tidak melihat ingatan itu dibebaskan tepat waktu dan pergi mencari korban lain. Beberapa dari mereka mungkin sangat penting untuk operasi sistem.

selain malloc / mmap, ini bisa disebabkan oleh cache FS yang tidak terciprat yang membutuhkan waktu lama (mis. dengan 30GB data yang tidak tercuci, dengan asumsi kecepatan disk 300 MB / detik, mungkin diperlukan 100 detik untuk mem-flush-nya). Bahkan pada tingkat itu, OOM mungkin terlalu tidak sabar. Atau, OOM membunuh rsync tidak memulai FS flush cukup cepat [atau sama sekali]. Atau FS flush terjadi cukup cepat, tetapi memiliki rilis halaman "malas" ke kolam gratis. Ada beberapa opsi / proc yang dapat Anda atur untuk mengontrol perilaku cache FS [Saya tidak ingat apa itu].

Coba boot dengan mem = 4G atau angka kecil lainnya. Ini dapat mengurangi cache FS dan mempersingkat waktu flush-nya untuk mencegah OOM mencari hal-hal lain untuk dibunuh (mis. Flush time berkurang dari 100 detik menjadi <1 detik). Mungkin juga membuka kedok bug OOM yang tidak dapat menangani ram fisik> 4GB pada sistem 32 bit atau semacamnya.

Juga, poin penting: Jalankan sebagai non-root. Pengguna root tidak pernah diharapkan untuk mengunyah sumber daya, sehingga mereka diberi batas lebih memaafkan (misalnya 99% dari memori vs 95% untuk pengguna non-root). Ini mungkin menjelaskan mengapa OOM berada dalam kondisi seperti itu. Juga, ini memberi OOM et. Al. lebih banyak ruang kepala untuk melakukan tugasnya merebut kembali ingatan.


Lihat Berapa banyak ruang SWAP pada sistem memori tinggi? - dan Anda tidak ingin melihat sistem Anda menggunakan 63GB swap. Itu tidak akan bisa digunakan.
Reinstate Monica - M. Schröder

1
swap> RAM hanya sangat berguna jika Anda menjalankan tanpa VM overcommit, sehingga kernel perlu memesan ruang swap untuk halaman yang dialokasikan sampai mereka kotor dan membutuhkan halaman fisik nyata yang mendukungnya. Praktek saat ini adalah untuk memungkinkan overcommit, dan dijalankan dengan sejumlah kecil ruang swap untuk mengeluarkan halaman yang hanya disentuh saat startup dan tidak diperlukan dalam operasi normal. overcommit = 0 dengan swap kecil baik-baik saja jika Anda memiliki banyak RAM, untuk sebagian besar sistem.
Peter Cordes

Tampaknya rsync benar - benar mencoba menggunakan> 32GB, sehingga swap diperlukan untuk itu. Artinya, rsync akan menggunakan 50GB untuk file ini. 2x telah menjadi metrik yang telah dicoba dan benar selama 30 tahun. Karena disk 6TB adalah ~ $ 300, tidak ada alasan untuk tidak melakukannya. Apa lagi yang mungkin berjalan di server ini yang secara kolektif akan mendorong batas RAM?
Craig Estey

1
@CraigEstey 64 GB swap benar-benar konyol karena seperti yang saya sebutkan sebelumnya kami tidak memiliki proses pengguna yang besar, kami hanya ingin cache disk, dan seperti yang ditunjukkan oleh log saya, kami menggunakan swap NOL pada saat crash. NOL. Juga rsync menggunakan 600KB ram bahkan pada file 50GB. Kebingungan awal saya adalah bahwa mungkin linux secara agresif memegang cache disk. Dan akhirnya, saya ingin melihat beberapa angka atau dokumentasi tentang berapa banyak memori yang digunakan kernel untuk melacak ruang swap sebelum saya menambahkan lagi ke kotak ini.
dataless

@atalatal Saya telah menambahkan informasi tambahan yang sepenuhnya menjelaskan apa yang terjadi dan mengapa. rsync adalah meraih memori melalui malloc / mmap dan akan pergi untuk 50GB sebelum hal itu dilakukan. Lihat bagian yang diperbarui. Ini memiliki tes yang dapat membuktikan / menyangkal apa yang saya katakan dan Anda dapat melewatkan swap ditambahkan pada awalnya untuk menguji. BTW, saya sudah pemrograman kernel / driver untuk 40 + tahun - saya mungkin hanya tahu sesuatu yang tidak Anda, jadi silakan moderat nada - saya sedang mencoba untuk membantu.
Craig Estey

2

clamd? Kedengarannya seperti Anda menggunakan ClamAV dan pemindaian saat akses diaktifkan ketika mesin anti-virus mencoba memindai file yang dibuka untuk virus, dengan memuat ke dalam memori, seluruh konten dari setiap file dibuka oleh proses lain .

Bergantung pada postur keamanan Anda dan perlunya transfer ini, Anda harus mengevaluasi menonaktifkan pemindaian akses-ClamAV saat Anda melakukan transfer.


Saya tidak tahu ini bahkan bisa dilakukan clamav ... tapi tidak, kami hanya memindai file-file tertentu yang disalurkan dari clamc. Juga, 32-bit, jadi tidak ada bahaya clamav memonopoli semua memori sistem. (Anda tahu mengapa kami berpikir 32-bit masih merupakan ide yang bagus?)
dataless

1
Kernel Linux melaporkan bahwa clamd adalah proses yang permintaan alokasi memorinya memanggil pembunuh OOM - ClamAV hampir pasti merupakan penyebab sekunder (penyebab utama tidak cukupnya memori). Baik itu pemindaian saat akses atau konfigurasi lainnya, semua tanda mengarah ke ClamAV.
oo.

Lain kali Anda memulai rsync, jalankan top dan pantau ukuran resident dari proses clamd.
oo.

clamd adalah proses pertama untuk memanggil oom killer, tetapi juga yang pertama mati karena beratnya hampir 42MB (salah satu proses yang lebih besar di server). The oom_killer berjalan berulang kali setelah ini sampai metalog terbunuh.
dataless
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.