Rsync, Linux OOM katilini tek bir 50 GB'lik dosyada tetikledi


66

Server_A'da tek bir 50 GB dosyam var ve onu server_B'ye kopyalıyorum. koşarım

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

Server_B, 2 GB takas ile 32 GB RAM'e sahiptir. Çoğunlukla boşta ve çok fazla boş RAM olmalıydı. Bol miktarda disk alanı var. Yaklaşık 32 GB'de, transfer uzak tarafın bağlantıyı kapatmasından dolayı iptal edilir.

Server_B şimdi ağdan ayrıldı. Veri merkezinden yeniden başlatmasını istiyoruz. Çekirdek günlüğüne çökmeden önce baktığımda, 0 bayt takas kullandığını ve işlem listesinin çok az bellek kullandığını gördüm (rsync işlemi 600 KB RAM kullanıyordu), ancak oom_killer çılgına dönüyor ve kütükteki son şey, metaloğunun çekirdek okuyucu sürecini öldürdüğü yer.

Bu, çekirdek 3.2.59, 32-bit'dir (bu nedenle hiçbir işlem 4 GB'den daha fazla eşlenemez).

Neredeyse Linux, uzun ömürlü koşu çalışanlarından daha önbelleklemeye daha fazla öncelik veriyormuş gibi. Ne oluyor?? Ve bunun tekrar olmasını nasıl durdurabilirim?

İşte oom_killer'ın çıktısı:

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

İşte benim rsync komutumu root olmayan bir kullanıcı olarak tekrarladıktan sonra 'top' çıktısı:

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

İşte sysctl vm parametreleri:

# 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
Çekirdek kilitlenme mesajlarını okuma konusunda uzman değilim, ancak B'nin 32GB çekirdek kullandığına dair herhangi bir belirti göremiyorum. Olduğu varsayımına devam etmeden önce, şu anda olduğunu onaylayabilir misiniz? Çünkü 32GB çekirdek çekirdekli bir kutuyu ve sadece 4 GB çekirdeği tüketen bir bellek arasında büyük bir fark var.
MadHatter

En iyi çıktı ile güncellendi. Bu, root olmayan bir kullanıcı ile aynı rsync komutunu çalıştırdıktan sonra. 1GB dışındakilerin hemen hepsi şu anda önbellek için kullanılıyor.
dataless

Teşekkürler. Dediğim gibi, ben uzman değilim - ama kontrol etmeye değer gibiydi.
MadHatter

ayrıca çekirdeğinizin değiştirmeye izin verdiğini de doğrulamalısınız (yani, değiştirme kapalı değildir) (ve daha büyük bir disk alanı ayırmanız gerekir, diyelim ki 16 Gb veya hatta 32 Gb). İnternetteki bazı garip insanlar takası kapatmayı tavsiye ediyor ki bu çok yanlış.
Olivier Dulac

@OlivierDulac hangi ayardan bahsediyorsunuz? takas desteği derlenmiştir ya da takas yapamayız ve 'takas' 60'a ayarlanmıştır. Takas büyüklüğüne gelince, bu sorunu 32 bit çekirdeğin üzerinde daha da kötüleştirmez mi? Cevap, çekirdek veri yapılarının bizi öldüren şey olduğu görünüyor. 32GB kullanıcı işlemi yapmıyoruz, sadece performans için disk önbellek için bu kadar ram istiyoruz.
dataless

Yanıtlar:


178

Öyleyse oom katil çıktısını okuyalım ve oradan ne öğrenilebileceğini görelim.

OOM katil kütüklerini analiz ederken, onu neyin tetiklediğine bakmak önemlidir. Günlüğünüzün ilk satırı bize bazı ipuçları verir:

[çekirdek] [1772321.850644] istiridye oom- katil'i çağırdı: gfp_mask = 0x84d0, sipariş = 0

order=0bize ne kadar hafıza talep edildiğini söylüyor. Çekirdek bellek yönetimi, sayfa numaralarını yalnızca 2 olanın gücünde yönetebilir, bu nedenle istiridye 2 0 sayfa bellek veya 4 KB talep etmiştir.

GFP_MASK'in en düşük iki biti (serbest sayfa maskesini alın), sözde bölge maskesini , tahsisatçıya hangi bölgeden hafızayı alacağını söyleyen bölge maskesini oluşturur :

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

Bellek bölgeleri , temel olarak uyumluluk nedenleriyle oluşturulan bir kavramdır. Basitleştirilmiş bir görünümde, bir x86 Çekirdeği için üç bölge vardır:

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

Senin durumunda, zonemask 0, yani istiridye ondan bellek istediği anlamına gelir ZONE_NORMAL.

Diğer bayraklar çözülüyor

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

göre Linux MM belgelerinde , bu nedenle requst için bayraklar vardır GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOve GFP_WAITböylece özellikle seçici olmama,.

Peki neyin var ZONE_NORMAL? Bazı genel istatistikler OOM çıktısında daha ileride bulunabilir:

[çekirdek] [1772321.850770] Normal serbest: 8056kB min: 8048kB düşük: 10060kB yüksek: 12072kB aktif_anon: 0kB aktif değil_anon: 0kB aktif_file: 248kB aktif olmayan_file: 388kB değişmez: 0kB: izole edilmiş (0B: 898: 0k: 0B: (0000):

Burada göze çarpan, bu freesadece 8K'nın minaltında ve altında low. Bu, ana makinenizin hafıza yöneticisinin bir miktar sıkıntıda olduğu ve kswapd'ın, aşağıdaki grafiğin sarı aşamasında olduğu gibi sayfaları zaten değiştirmesi gerektiği anlamına gelir : Linux bellek yöneticisi grafiği

Bölgenin hafıza parçalanması hakkında daha fazla bilgi burada verilmiştir:

[çekirdek] [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

temelde 4 MB'lık tek bir bitişik sayfaya sahip olduğunuzu, gerisinin ağırlıklı olarak 4KB sayfalara bölündüğünü belirtir.

Öyleyse özetleyelim:

  • Eğer (a kullanım alanı süreç clamdbellek alma) ZONE_NORMALgenellikle gerçekleştirilebilir olur ayrıcalıklı olmayan bellek ayırma iseZONE_HIMEM
  • Hafıza yöneticisi bu aşamada istenen 4K sayfasını sunabilmiş olmalıdır, ancak ZONE_NORMAL
  • Sistem, kswapdkuralları gereği, önceden bir sayfalama faaliyeti görmüş olmalıydı , ancak ZONE_NORMALaçık bir neden olmadan hafıza baskısı altında bile hiçbir şey değişmiyordu.
  • Yukarıdakilerin hiçbiri neden oom-killerçağrıldığına dair kesin bir neden vermemektedir.

Bunların hepsi garip görünüyor, ancak en azından John O'Gorman'ın "Linux Sanal Bellek Yöneticisini Anlama" kitabının 2.5 bölümünde açıklananlarla ilgili olması gerekiyor :

Çekirdeğin kullanabileceği adres alanının (ZONE_NORMAL) boyutu sınırlı olduğundan, çekirdeğin Yüksek Bellek kavramını desteklemesi gerekir. [...] 1GiB ve 4GiB aralığında belleğe erişmek için, çekirdek geçici olarak yüksek bellekten gelen sayfaları kmap () ile ZONE_NORMAL içinde eşler. [...]

Bu, 1GiB belleği tanımlamak için, yaklaşık 11MiB çekirdek belleğinin gerekli olduğu anlamına gelir. Böylece, 16GiB ile, 176MiB bellek tüketilir ve ZONE_NORMAL üzerinde önemli bir baskı oluşturur. ZONE_NORMAL kullanan diğer yapılar dikkate alınana kadar bu çok kötü gelmiyor. Sayfa Tablosu Girdileri (PTE'ler) gibi çok küçük yapılar bile en kötü durumda yaklaşık 16MiB gerektirir. Bu, 16GiB'yi bir x86'daki kullanılabilir fiziksel bellek Linux için pratik sınırlama hakkında yapar .

(vurgu benimdir)

3.2'nin hafıza yönetiminde 2.6'nın üzerinde sayısız ilerlemesi olduğundan, bu kesin bir cevap değil, ilk önce izleyeceğim çok güçlü bir ipucu. mem=Çekirdek parametresini kullanarak veya DIMM'lerin yarısını sunucudan sökerek ana bilgisayarın kullanılabilir belleğini en fazla 16G'ye düşürün .

Sonunda, 64 bit Çekirdek kullanın .

Dostum, 2015.


13
Yukarıda derken " ben uzman değilim ," Bu Okumayı umuyordum şeydir. +1000, eğer yapabilseydim; +1 kesin. Ne güzel bir cevap!
MadHatter 24:15

18
Bu çok güzeldi. SF için hala umut var.
Roma

9
@dataless Evet. ZONE_NORMAL’inizin tümünün üst bellek bölgeleriyle ilgili meta verilerle dolu olduğundan şüpheleniyorum. Bir kullanıcı alanı işlemi bellek sayfaları isterken, büyük olasılıkla ZONE_HIGHMEM (HIGHMEM'in isteği yerine getirecek başka sayfa yoksa, NORMAL'ın sahip olduğu NORMAL ise, ZONE_HIGHMEM bellek baskısı altında değilse) ZONE_HIGHMEM talebinde bulunacaktır. (sizinki değil), ZONE_NORMAL kullanıcı alanı işlem sayfasına sahip olmayacak.
the-wabbit

3
[slams klavyede yumruklar] Bu wabbit'e lütuf ver
underscore_d

3
@ the-wabbit Sıcak ağ soruları.
CodesInChaos 28:15

4

Bir kaç şey ...

Takas alanı için temel kuralım, fiziksel koç miktarının en az 2 katı kadar olmuştur. Bu sayfa / takas daemon belleğini verimli bir şekilde yeniden açma yeteneğini sağlar.

Server_B'de 32GB koç var, bu yüzden 64GB takas için yapılandırmayı deneyin. IMO, sunucu sahip takas alanı 2GB yolu özellikle bir sunucu için, çok düşük.

Bir takas bölümünü oluşturabileceğiniz fazladan bir bölümünüz yoksa, bunu bir dosya oluşturarak ve bir takas bölümü olarak monte ederek test edebilirsiniz (yavaş olacaktır). Bakınız https://www.maketecheasier.com/swap-partitions-on-linux/

Server_B bol miktarda disk alanına sahip olduğundan, --inplace gerekli değildir ve rsync'in 32GB kullanmasına neden olan şey olabileceği için istenmeyebilir. --inplace yalnızca, dosya sistemi alanında [olmadığınız] yetersizseniz veya bazı özel performans gereksinimleriniz varsa kullanışlıdır.

Tahminim şu ki, rsync, mevcut seçeneklerinizle 50GB ram [dosya boyutu] kullanmak isteyecektir. Normalde, rsync işini yapmak için bu kadar belleğe ihtiyaç duymaz, bu nedenle seçeneklerinden biri veya daha fazlası sorun olabilir. 200GB dosyalarımı sorunsuz bir şekilde aktarıyorum.

Seçenek yok kullanarak bazı deneme çalıştırmaları yapın. Bunu daha küçük dosyalar ile yapın, 10 GB deyin - bu, çekirdek panikini engellemeli ancak yine de soruna neden olan davranışı izlemenizi sağlar. RSync'in bellek kullanımını izleyin.

Kademeli olarak, hangi seçeneğin [veya seçeneklerin kombinasyonunun] rsync'in RAM'da pigment atmasına neden olduğunu görmek için (örneğin, transfer olurken, rsync'in ram kullanımı, aktarılan dosya verisi miktarıyla orantılı olarak artar) görmek için, her seferinde bir seçenek ekleyin. vb.).

Eğer gerçekten rsync'in ram içi dosya görüntüsünü korumasına neden olan seçeneklere gerçekten ihtiyacınız varsa, ekstra takas alanına ihtiyacınız olacak ve maksimum dosya boyutunuz buna göre sınırlanacaktır.

Birkaç şey daha [GÜNCELLEME]:

(1) Çekirdek yığın izlemesi, rsync'in mmap alanında sayfa hatası yaptığını gösteriyor. Muhtemelen dosyayı eşleştiriyordur. mmap , dosya kapatılıncaya kadar (okuma / yazma işleminden farklı olarak) FS bloğu önbelleğine derhal [temizleneceği yer] diske gireceği konusunda hiçbir garanti vermez

(2) Çekirdek çökmesi / paniği, aktarma boyutu RAM boyutuna ulaştığında gerçekleşiyor. Açıkçası rsync, bu kadar fscache olmayan belleği malloc veya mmap üzerinden alıyor. Bir kez daha, belirttiğiniz seçeneklerle, rsync, 50 GB'lik bir dosyayı aktarmak için 50GB'lık bellek ayıracak.

(3) 24GB'lık bir dosya aktarın. Muhtemelen işe yarayacak. Ardından çekirdeği mem = 16G ile başlatın ve 24GB dosya testini tekrar yapın. 32GB yerine 16GB'da patlayacak. Bu, rsync'in gerçekten belleğe ihtiyacı olduğunu doğrular.

(4) Takas eklemenin saçma olduğunu söylemeden önce, bazılarını [takas-dosya yöntemi ile] eklemeyi deneyin. Bu, takas işleminin nasıl yapıldığına dair tüm akademik argümanlardan çok daha kolaydır. Çözüm olmasa bile, ondan bir şey öğrenebilirsiniz. Mem = 16G testinin panik / çarpışma olmadan başarılı olacağını iddia edeceğim.

(5) Şansı rsync olan bir takas isabet, ancak içinde OOM tekmeler önce üst göremeyecek hızlı olur ve rsync öldürür. Rsync 32GB’ye ulaştığında, özellikle boşta kalmaları durumunda, diğer işlemler çoktan değişmeye zorlandı. Belki de, "özgür" ve "üst" bir arada size daha iyi bir görüntü verecektir.

(6) RSync öldürüldükten sonra mmap'i FS'ye yıkamak zaman alır. OOM için yeterince hızlı değil ve başka şeyleri öldürmeye başlıyor (bazıları açıkça kritiktir). Yani, mmap floş ve OOM yarışıyor. Veya OOM’da bir hata var. Aksi takdirde, bir kaza olmazdı.

(7) Deneyimlerime göre, bir sistem "hafıza duvarına çarptığında", Linux'un tamamen iyileşmesi uzun zaman alıyor. Ve bazen hiçbir zaman tam olarak düzgün bir şekilde iyileşmez ve temizlemenin tek yolu yeniden başlatmadır. Örneğin, 12GB RAM'im var. 40GB bellek kullanan bir iş çalıştırdığımda (büyük işleri yapabilmek için 120 GB'lık takaslarım var) ve sonra onu öldürdüğümde, sistemin normal yanıt vermeye geri dönmesi yaklaşık 10 dakika sürüyor [disk her zaman sabit yanıyor] .

(8) rsync çalıştırın olmadan seçenekleri. Bu çalışacak. Çalışmak için bir temel örnek alın. Sonra tekrar yerine ekleyin ve tekrar test edin. Ardından --append-doğrulayın. Sonra ikisini de deneyin. Hangi seçeneğin rsync'i dev mmap yaptığını öğren. O zaman onsuz yaşayabileceğine karar ver. Eğer --inplace suçlu ise, bu hiç de akıllıca olmaz, çünkü bol disk alanınız var. Bu seçeneğe sahip olmanız gerekiyorsa, rsync'in yapacağı malloc / mmap bileşenine uyum sağlamak için takas alanını elde etmeniz gerekir.

İKİNCİ GÜNCELLEME:

Lütfen mem = 'i ve daha küçük dosya testlerini yukarıdan yapın.

Temel sorular: rsync neden OOM tarafından öldürülüyor? Kim / hafızayı çiğnemek nedir?

Sistemin 32 bit olduğunu [unuttum] okudum. Bu nedenle, rsync doğrudan sorumlu olmayabilir (malloc / mmap - glibc aracılığıyla anonim / özel mmapler yoluyla büyük malloclar uygular) ve rsync'nin mmap sayfa hatası sadece OOM'u tesadüfen tetikler. Ardından, OOM, rsync tarafından doğrudan ve dolaylı olarak tüketilen toplam belleği hesaplar [FS önbellek, soket arabellekleri, vb.] Ve bunun birincil aday olduğuna karar verir. Bu nedenle, toplam bellek kullanımını izlemek yardımcı olabilir. Dosya aktarımıyla aynı oranda süründüğünden şüpheleniyorum. Açıkçası, olmamalı.

/ Proc veya / proc / rsync_pid içinde bir perl veya python betiği ile hızlı bir döngüde izleyebileceğiniz bazı şeyler [bir bash betiği muhtemelen tüm dünya olayları için yeterince hızlı olmayacaktır] aşağıdaki birkaç yüz kez / sn. Bunu rsync'den daha yüksek bir öncelikte çalıştırabilirsiniz, böylece RAM'de çalışır ve çalışır, böylece kazadan hemen önce ve umarım OOM sırasında olayları izleyebilir ve OOM'un neden çılgına döndüğünü görebilirsiniz:

/ proc / meminfo - takas kullanımında "etki noktası" nda daha iyi tahıl elde etmek için. Aslında, ne kadar RAM kullanıldığına dair son numarayı almak daha yararlı olabilir. Top bunu sağlarken, "büyük patlama" dan hemen önce evrenin durumunu gösterecek kadar hızlı olmayabilir (örneğin, son 10 milisaniye)

/ proc / rsync_pid / fd dizini. Sembolik linkleri okumak, hedef dosyada hangi fd'nin açıldığını belirlemenize izin verecektir (örn. / Proc / rsync_pid / fd / 5 -> target_file dosyasının readlink). Bu muhtemelen fd numarasını almak için sadece bir kez yapılmalı [sabit kalmalı]

Fd sayısını bilmek, / proc / rsync_pid / fdinfo / fd dosyasına bakın. Şuna benzeyen bir metin dosyası:

pos: <file_position>
bayraklar: blah_blah
mnt_id: blah_blah

"Pos" değerinin izlenmesi yararlı olabilir çünkü "son dosya konumu" yararlı olabilir. Farklı boyutlarda ve mem = seçenekleriyle birkaç test yaparsanız, son dosya konumu bunlardan herhangi birini [ve nasıl] izler mi? Olağan şüpheli: dosya konumu == kullanılabilir RAM

Ancak, en basit yol "rsync local_file server: remote_file" ile başlamak ve çalıştığını doğrulamaktır. "Önce ssh server rsync file_a file_b" [önce 50GB dosya_a oluşturmanız gerekir] 'i kullanarak benzer [ancak daha hızlı] sonuçlar elde edebilirsiniz. File_a oluşturmanın basit bir yolu scp local_system: original_file server: file_a ve bu kendi başına ilginç olabilir (örneğin, rsync çöktüğünde işe yarıyor mu? NIC sürücüsü gibi başka bir şeye). Ssh rsync'in yapılması NIC'yi denklemden çıkarır, bu da faydalı olabilir. Bu sistemi hortumlarsa, bir şey gerçekten yanlış. Başarılı olursa, [bahsettiğim gibi] seçenekleri birer birer geri eklemeye başlar.

Asıl mesele olmaktan nefret ediyorum, ancak dosyaya takas yoluyla bazı takas yapmak çarpışma davranışını değiştirebilir / geciktirebilir ve tanı aracı olarak yararlı olabilir. Eğer 16GB diyelim ki takas değişimi, [hafıza kullanımı veya hedef dosya konumu ile ölçülen] çökmeyi 32GB'tan 46GB'a kadar geciktirirse, o zaman bu bir şey söyleyecektir.

Belirli bir işlem olmayabilir, ancak belleği çiğneyen hatalı bir çekirdek sürücüsü. Çekirdeğin iç vmallocu bir şeyler tahsis eder ve değiştirebilir. IIRC, her koşulda adreslenebilirliğe bağlı değildir.

Açıkçası, OOM'un kafası karışıyor / panikleniyor. Yani, rsync'i öldürür, ancak hafızanın zamanında boşaldığını görmez ve diğer kurbanları aramaya gider. Bazıları muhtemelen sistemin çalışması için kritik öneme sahiptir.

malloc / mmap bir yana, bunun nedeni uzun zaman alan temizlenmiş FS önbelleklerinden kaynaklanıyor olabilir (örn. 300 MB / sn'lik bir disk hızı varsayarsak temizlemesi 100 saniye alabilir). Bu oranda bile, OOM çok sabırsız olabilir. Veya, OOM öldürme rsync FS'yi yeterince hızlı bir şekilde başlatmıyor (veya hiç). Veya FS temizlemesi yeterince hızlı gerçekleşir, ancak sayfaların serbest havuza geri döndüğü "tembel" bir sürümüne sahiptir. FS önbellek davranışını kontrol etmek için ayarlayabileceğiniz bazı / proc seçenekleri vardır [Ne olduklarını hatırlayamıyorum].

Mem = 4G veya başka bir küçük numara ile önyüklemeyi deneyin. Bu, FS önbelleğini kesebilir ve OOM'un öldürülecek diğer şeyleri aramasını engellemek için temizleme süresini kısaltabilir (örn. Temizleme süresi 100 saniyeden <1 saniyeye düşürülür). Ayrıca, 32 bitlik bir sistemde ya da bazılarında fiziksel ram> 4GB ile başa çıkamayan bir OOM hatasını gizleyebilir.

Ayrıca, önemli bir nokta: Kök olmayan olarak çalıştırın. Kök kullanıcılarının hiçbir zaman kaynakları çiğnemeleri beklenmez, bu yüzden daha fazla bağışlayıcı sınırlar verilir (örneğin, belleğin% 99'u ile root olmayan kullanıcılar için% 95). Bu, OOM'in neden böyle bir durumda olduğunu açıklayabilir. Ayrıca, bu OOM et. ark. hafızayı geri kazanma işini yapmak için daha fazla boşluk var.


Bkz. Yüksek bellek sisteminde ne kadar SWAP alanı var? - ve sisteminizin 63GB takas kullandığını görmek istemezsiniz. Kullanılamayacak.
Monica’yı eski durumuna getirin - M. Schröder

1
swap> RAM, yalnızca VM fazla çalışma olmadan çalıştırıyorsanız gerçekten kullanışlıdır, bu nedenle çekirdeğin tahsis edilen sayfalar için, değiştirilinceye kadar takas alanını ayırması ve onları destekleyen gerçek fiziksel sayfalara ihtiyaç duyması gerekir. Şu anki uygulama, fazla çalışmaya izin vermek ve yalnızca başlangıçta dokunulan ve normal işletimde gerekmeyen sayfaların sayfalarını çıkarmak için az miktarda takas alanıyla çalışmaktır. Fazla sistemde = 0 varsa, çoğu sistemde çok RAM varsa
Peter Cordes

O rsync gerçekten göründüğü edilir > 32GB kullanmaya çalışıyor, bu yüzden takas bunun için gereklidir. Yani, rsync bu dosya için 50GB kullanacak. 2x 30 yıldır denenmiş ve gerçek bir ölçü. Bir 6TB disk ~ 300 $ olduğundan, yapmamak için hiçbir sebep yoktur. Bu sunucuda toplu olarak RAM limitini aşacak başka ne çalışıyor olabilir?
Craig Estey

1
@CraigEstey Daha önce de belirttiğim gibi büyük kullanıcı işlemlerine sahip olmadığımız için yalnızca disk önbelleğini istiyoruz ve günlüğümün gösterdiği gibi, çarpışma sırasında SIFIR takas kullanıyorduk çünkü 64 GB takas alanı tamamen saçma. SIFIR. Ayrıca rsync, 50GB'lik bir dosyada bile 600KB ram kullanıyor. İlk kargaşam, belki linux'nun agresif bir şekilde disk önbelleğini tutmasıydı. Sonunda, bu kutuya daha fazla eklemeden önce çekirdeğin takas alanını izlemek için ne kadar bellek kullandığı hakkında bazı numaralar veya belgeler görmek istiyorum.
dataless

@dataless Neler olduğunu ve neden olduğunu tam olarak açıklayan ek bilgiler ekledim. rsync , belleği malloc / mmap ile tutuyor ve bitmeden 50GB'ye çıkacak. Güncellenen bölüme bakınız. Söylediklerimi ispatlayabilen / ispatlayabilen testler var ve test etmek için başlangıçta eklenmiş takası atlayabilirsiniz. BTW, 40 + yıldır çekirdekleri / sürücüleri programlama oldum - ben - ben sadece, bu yüzden sesi orta lütfen bir şeyi biliyor olabilir am yardım etmeye çalışıyor.
Craig Estey

2

clamd'a? ClamAV kullanıyormuş gibi görünüyorsunuz ve antivirüs motorunun açık dosyaları virüs taraması yapmaya çalıştığı erişimde tarama özelliği etkinleştirilmiş gibi görünüyor , başka bir işlem tarafından açılan tüm dosyaların içeriğini belleğe yükleyerek .

Güvenlik duruşunuza ve bu aktarımın gerekliliğine bağlı olarak, aktarımı gerçekleştirirken ClamAV erişimde tarama işlemini devre dışı bırakmayı değerlendirmelisiniz.


Bunun clamav'ın yapabileceği bir şey olduğunu bile bilmiyordum ... ama hayır, sadece clamc'dan ona aktarılan belirli dosyaları taradık. Ayrıca, 32-bit, bu yüzden tüm sistem belleğini tıkama clamav tehlikesi. (32-bit'in neden hala iyi bir fikir olduğunu düşündüğümüzü
anlıyor

1
Linux çekirdeği istiridye, bellek ayırma talepleri OOM katilini çağıran süreçtir - ClamAV neredeyse kesinlikle ikincil nedendir (birincil neden yeterli bellek değildir). Erişimde tarama veya başka bir yapılandırmada olsun, tüm işaretler ClamAV'ya işaret ediyor.
oo.

Bir dahaki sefere rsync'i başlattığınızda, en üste gelin ve istiridye işleminin asıl boyutunu izleyin.
oo.

istiridye oom katili çağırdı ilk süreç, aynı zamanda neredeyse 42 MB (sunucudaki daha büyük işlemlerden biri) ağırlığında olduğundan ölen ilk süreç oldu. Oom_killer bundan sonra metalo bile öldürülünceye kadar tekrar tekrar çalışıyor.
dataless
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.