
У меня есть один файл размером 50 ГБ на сервере server_A, и я копирую его на сервер server_B. Я запускаю
server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file
Server_B имеет 32 ГБ ОЗУ с 2 ГБ подкачки. Он в основном простаивает и должен был иметь много свободной ОЗУ. У него много дискового пространства. Приблизительно на 32 ГБ передача прерывается, поскольку удаленная сторона закрыла соединение.
Server_B теперь отключился от сети. Мы просим центр обработки данных перезагрузить его. Когда я смотрю на журнал ядра до его сбоя, я вижу, что он использовал 0 байт подкачки, а список процессов использовал очень мало памяти (процесс rsync был указан как использующий 600 КБ ОЗУ), но oom_killer сходил с ума, и последнее, что есть в журнале, это то, как он убивает процесс чтения ядра metalog.
Это ядро 3.2.59, 32-битное (поэтому ни один процесс в любом случае не сможет отобразить более 4 ГБ).
Это почти как если бы Linux отдал больший приоритет кэшированию, чем долгоживущим демонам. Что происходит?? И как я могу остановить это от повторения?
Вот вывод 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
Вот вывод «top» после повторения моей команды rsync от имени пользователя без прав 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
Вот параметры 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
решение1
Давайте прочитаем вывод oom-killer и посмотрим, что можно из него извлечь.
При анализе журналов OOM killer важно посмотреть, что его вызвало. Первая строка вашего журнала дает нам некоторые подсказки:
[ядро] [1772321.850644] clamd вызвал oom-killer:gfp_mask=0x84d0, порядок=0
order=0
сообщает нам, сколько памяти запрашивается. Управление памятью ядра может управлять только страницами, номер которых равен степени 2, поэтому clamd запросил 20 страниц памяти или 4КБ.
Два младших бита GFP_MASK (маска получения свободной страницы) составляют так называемуюзональная маска сообщая распределителю, из какой зоны брать память:
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
Зоны памятиэто концепция, созданная в основном из соображений совместимости. В упрощенном виде, есть три зоны для ядра 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
В вашем случае zonemask равен 0, что означает, что clamd запрашивает память из ZONE_NORMAL
.
Остальные флаги разрешаются
/*
* 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 */
в соответствии сДокументация Linux MM, поэтому ваш запрос имеет флаги для GFP_ZERO
, GFP_REPEAT
, GFP_FS
, GFP_IO
и GFP_WAIT
, поэтому не является особенно придирчивым.
Так в чем дело ZONE_NORMAL
? Некоторые общие статистические данные можно найти далее в выводе OOM:
[ядро] [1772321.850770] Нормальныйсвободно:8056kB мин:8048kB мало:10060kBвысокий: 12072 КБ активный_анон: 0 КБ неактивный_анон: 0 КБ активный_файл: 248 КБ неактивный_файл: 388 КБ неискоренимый: 0 КБ изолированный(анон): 0 КБ изолированный(файл): 0 КБ присутствует: 890008 КБ
Здесь заметно, чтоfree
всего в 8К отmin
и путь подlow
. Это означает, что диспетчер памяти вашего хоста находится в некотором затруднении, и kswapd должен уже подкачивать страницы, как это происходит вжелтыйфаза графика ниже:
Более подробная информация о фрагментации памяти зоны приведена здесь:
[ядро] [1772321.850795] Нормально: 830*4кБ 80*8кБ 0*16кБ 0*32кБ 0*64кБ 0*128кБ 0*256кБ 0*512кБ 0*1024кБ 0*2048кБ 1*4096кБ = 8056кБ
по сути, это означает, что у вас есть одна непрерывная страница размером 4 МБ, а остальная часть сильно фрагментирована на страницы в основном по 4 КБ.
Итак, давайте подведем итоги:
- у вас есть пользовательский процесс (
clamd
), получающий памятьZONE_NORMAL
, тогда как непривилегированное выделение памяти обычно выполняется изZONE_HIMEM
- На этом этапе диспетчер памяти должен был обслужить запрошенную страницу размером 4 КБ, хотя у вас, похоже, наблюдается значительная нехватка памяти.
ZONE_NORMAL
- система, по
kswapd
правилам,долженнаблюдал некоторую активность подкачки страниц ранее, но ничего не выгружается, даже при нехватке памяти вZONE_NORMAL
, без видимой причины - Ничто из вышеперечисленного не дает определенной причины, по которой
oom-killer
был применен
Все это кажется довольно странным, но, по крайней мере, имеет отношение к тому, что описано враздел 2.5 великолепной книги Джона О'Гормана «Понимание диспетчера виртуальной памяти Linux»:
Поскольку адресное пространство, используемое ядром (ZONE_NORMAL), ограничено по размеру, ядро поддерживает концепцию верхней памяти. [...] Для доступа к памяти в диапазоне от 1 ГБ до 4 ГБ ядро временно отображает страницы из верхней памяти в ZONE_NORMAL с помощью kmap(). [...]
Это означает, что для описания 1GiB памяти требуется около 11MiB памяти ядра. Таким образом, при 16GiB потребляется 176MiB памяти, что оказывает значительное давление на ZONE_NORMAL. Это не звучит так уж плохо, пока не будут приняты во внимание другие структуры, которые используют ZONE_NORMAL. Даже очень маленькие структуры, такие как Page Table Entries (PTE), требуют около 16MiB в худшем случае.Это делает 16 ГБ практическим пределом для доступной физической памяти Linux на x86..
(выделено мной)
Поскольку 3.2 имеет многочисленные усовершенствования в управлении памятью по сравнению с 2.6, это не точный ответ, но действительно сильный намек, который я бы использовал в первую очередь. Уменьшите полезную память хоста максимум до 16 ГБ, либо используя mem=
параметр ядра, либо вытащив половину DIMM из сервера.
В конечном счете,использовать 64-битное ядро.
Чувак, сейчас 2015 год.
решение2
Несколько вещей ...
Мое правило для пространства подкачки — иметь как минимум 2x объема физической памяти. Это позволяет демону страниц/подкачки эффективно реорганизовать память.
Server_B имеет 32 ГБ оперативной памяти, поэтому попробуйте настроить его на 64 ГБ подкачки. По моему скромному мнению, 2 ГБ подкачки на вашем сервере — этоспособслишком мало, особенно для сервера.
Если у вас нет дополнительного раздела, который можно сделать разделом подкачки, вы можете проверить это, создав файл и смонтировав его как раздел подкачки [это будет медленно]. Смотритеhttps://www.maketecheasier.com/swap-partitions-on-linux/
Поскольку на сервере server_B достаточно места на диске, параметр --inplace не нужен и может оказаться нежелательным, поскольку именно он может стать причиной использования rsync 32 ГБ. --inplace действительно полезен только в случае нехватки места на файловой системе [а это не так] или наличия особых требований к производительности.
Я предполагаю, что rsync захочет использовать 50 ГБ оперативной памяти [размер файла] с вашими текущими параметрами. Обычно rsync не нужно так много памяти для выполнения своей работы, так что один или несколько из ваших параметров могут быть проблемой. Я регулярно пересылаю файлы по 200 ГБ без проблем.
Выполните несколько тестовых запусков без опций. Сделайте это с файлами меньшего размера, скажем, 10 ГБ — это должно предотвратить панику ядра, но все равно позволит вам отслеживать поведение, вызывающее проблему. Контролируйте использование памяти rsync.
Постепенно добавляйте параметры по одному за раз, чтобы увидеть, какой параметр [или комбинация параметров] заставляет rsync начать потреблять слишком много оперативной памяти (например, во время передачи использование оперативной памяти rsync растет пропорционально объему переданных данных файла и т. д.).
Если вам действительно нужны параметры, заставляющие rsync сохранять образ файла в оперативной памяти, вам понадобится дополнительное пространство подкачки, и максимальный размер файла будет соответственно ограничен.
Еще несколько вещей [ОБНОВЛЕНО]:
(1) Трассировка стека ядра показывает, что rsync вызвал сбой страницы в области mmap. Вероятно, он mmap-файл. mmap не дает никаких гарантий, что он будет сброшен на дискдофайл закрывается [в отличие от чтения/записи], который сразу же попадает в кэш блоков FS [где он будет очищен]
(2) Паника/сбой ядра происходит, когда размер передачи достигает размера ОЗУ. Очевидно, что rsync захватывает столько не-fscache памяти через malloc или mmap. Еще раз, с указанными вами параметрами rsync выделит 50 ГБ памяти для передачи файла размером 50 ГБ.
(3) Перенесите файл размером 24 ГБ. Это, вероятно, сработает. Затем загрузите ядро с mem=16G и снова выполните тест файла размером 24 ГБ. Он вылетит на 16 ГБ, а не на 32 ГБ. Это подтвердит, что rsync действительно нуждается в памяти.
(4) Прежде чем говорить, что добавление swap — это смешно, попробуйте добавить немного [методом swap-to-file]. Это гораздо проще сделать и проверить, чем все академические аргументы о том, что swap не нужен. Даже если это не решение, вы можете извлечь из этого урок. Держу пари, что тест mem=16G пройдет успешно без паники/сбоя.
(5) Скорее всего, rsyncявляетсянажимаю swap, но это происходит слишком быстро, чтобы увидеть с top, прежде чем OOM включится и убьет rsync. К тому времени, как rsync достигнет 32 ГБ, другие процессы уже будут вынуждены перейти на swap, особенно если они простаивают. Возможно, комбинация "free" и "top" даст вам лучшую картину.
(6) После того, как rsync будет убит, требуется время, чтобы сбросить mmap на FS. Недостаточно быстро для OOM, и он начинает убивать другие вещи [некоторые, очевидно, критически важны для миссии]. То есть, сброс mmap и OOM гонятся. Или в OOM есть ошибка. Иначе не было бы сбоя.
(7) По моему опыту, как только система «упирается в стену памяти», Linux требуется много времени для полного восстановления. А иногда она вообще не восстанавливается должным образом, и единственный способ очистить ее — перезагрузка. Например, у меня 12 ГБ ОЗУ. Когда я запускаю задание, которое использует 40 ГБ памяти [у меня есть 120 ГБ подкачки для размещения больших заданий], а затем завершаю его, системе требуется около 10 минут, чтобы вернуться к нормальной отзывчивости [при этом индикатор диска горит постоянно].
(8) Запустить rsyncбезoptions. Это сработает. Получите базовый пример для работы. Затем добавьте обратно --inplace и повторите тестирование. Затем вместо этого используйте --append-verify. Затем попробуйте оба варианта. Выясните, какой вариант заставляет rsync выполнять огромный mmap. Затем решите, сможете ли вы обойтись без него. Если виновником является --inplace, то это очевидно, поскольку у вас много места на диске. Если вам необходим этот вариант, вам придется получить пространство подкачки для размещения malloc/mmap, который будет выполнять rsync.
ВТОРОЕ ОБНОВЛЕНИЕ:
Пожалуйста, выполните тесты mem= и меньшего файла, как указано выше.
Центральные вопросы: Почему rsync убивает OOM? Кто/что жрет память?
Я читал [но забыл] о том, что система 32-битная. Так что я согласен, rsync может не быть напрямую ответственным (через malloc/mmap — glibc реализует большие malloc через анонимные/частные mmap), а ошибка страницы mmap rsync просто вызывает OOM по совпадению. Затем OOM вычисляет общий объем памяти, потребляемый rsync напрямую и косвенно [кэш FS, буферы сокетов и т. д.], и решает, что это главный кандидат. Так что мониторинг общего использования памяти может быть полезен. Я подозреваю, что он растет с той же скоростью, что и передача файлов. Очевидно, что этого не должно быть.
Некоторые вещи вы можете отслеживать в /proc или /proc/rsync_pid через скрипт perl или python в быстром цикле [скрипт bash, вероятно, не будет достаточно быстрым для события конца света], который может отслеживать все следующее несколько сотен раз в секунду. Вы можете запустить это с более высоким приоритетом, чем rsync, чтобы он оставался в оперативной памяти и работал, так что вы можете отслеживать вещи непосредственно перед сбоем и, надеюсь, во время OOM, чтобы вы могли понять, почему OOM сходит с ума:
/proc/meminfo -- для более точного определения использования подкачки в "точке удара". На самом деле, получение окончательного числа о том, сколько оперативной памяти используется в целом, может быть более полезным. Хотя top и предоставляет это, он может быть недостаточно быстрым, чтобы показать состояние вселенной непосредственно перед "большим взрывом" (например, последние 10 миллисекунд)
/proc/rsync_pid/fd каталог. Чтение символических ссылок позволит вам определить, какой fd открыт в целевом файле (например, readlink из /proc/rsync_pid/fd/5 --> target_file). Вероятно, это нужно сделать только один раз, чтобы получить номер fd [он должен оставаться фиксированным]
Зная номер fd, посмотрите на /proc/rsync_pid/fdinfo/fd. Это текстовый файл, который выглядит так:
поз: <позиция_файла> флаги: бла_бла mnt_id: бла_бла
Мониторинг значения "pos" может быть полезен, так как может быть полезна "последняя позиция файла". Если вы проводите несколько тестов с различными размерами и параметрами mem=, отслеживает ли последняя позиция файла что-либо из этого [и как]? Обычный подозреваемый: позиция файла == доступная RAM
Но самый простой способ — начать с «rsync local_file server:remote_file» и проверить, что это работает. Вы можете получить похожие [но более быстрые] результаты, выполнив «ssh server rsync file_a file_b» [вам сначала нужно будет создать file_a размером 50 ГБ]. Простой способ создать file_a — scp local_system:original_file server:file_a, и это может быть интересно само по себе (например, работает ли это, когда rsync дает сбой? Если scp работает, но rsync дает сбой, это указывает на rsync. Если scp дает сбой, это указывает на что-то другое, например, на драйвер сетевой карты). Выполнение ssh rsync также исключает сетевую карту из уравнения, что может быть полезно. Если это тормозит систему, значит, что-то действительно не так. Если это сработает, [как я уже упоминал] начните добавлять опции обратно по одной.
Ненавижу вдаваться в подробности, но добавление некоторого количества подкачки через swap-to-file может изменить/задержать поведение сбоя и может быть полезным в качестве диагностического инструмента. Если добавление, скажем, 16 ГБ подкачки задерживает сбой [измеренный по использованию памяти или положению целевого файла] с 32 ГБ до 46 ГБ, то это о чем-то говорит.
Это может быть не какой-то конкретный процесс, а сбойный драйвер ядра, который жрет память. Внутренний vmalloc ядра выделяет вещи, и их можно выгрузить. IIRC, он не ограничен адресуемостью при всех обстоятельствах.
Очевидно, OOM запутался/паникует. То есть, он убивает rsync, но не видит, что память освобождается вовремя, и отправляется на поиски других жертв. Некоторые из них, вероятно, критически важны для работы системы.
Помимо malloc/mmap, это может быть вызвано несброшенным кэшем FS, который занимает много времени (например, при 30 ГБ несброшенных данных, предполагая, что скорость диска составляет 300 МБ/с, может потребоваться 100 секунд, чтобы сбросить его). Даже при такой скорости OOM может быть слишком нетерпеливым. Или OOM, убивающий rsync, не запускает сброс FS достаточно быстро [или вообще не запускает]. Или сброс FS происходит достаточно быстро, но у него есть «ленивое» освобождение страниц обратно в свободный пул. Есть несколько параметров /proc, которые вы можете задать для управления поведением кэша FS [я не могу вспомнить, какие именно].
Попробуйте загрузиться с mem=4G или каким-то другим небольшим числом. Это может сократить кэш FS и сократить время его очистки, чтобы не дать OOM искать другие вещи для уничтожения (например, время очистки сокращается со 100 сек до < 1 сек). Это также может раскрыть ошибку OOM, которая не может обработать физическую оперативную память > 4 ГБ на 32-битной системе или что-то в этом роде.
Также важный момент: Запуск от имени не-root. От пользователей root никогда не ожидается, что они будут потреблять ресурсы, поэтому им даны более щадящие ограничения (например, 99% памяти против 95% для пользователей не-root). Это может объяснить, почему OOM находится в таком состоянии. Кроме того, это дает OOM и др. больше пространства для выполнения своей работы по восстановлению памяти.
решение3
clamd? Похоже, вы используете ClamAV и у вас включено сканирование при доступе, когда антивирусный движок пытается сканировать открытые файлы на наличие вирусов,путем загрузки в память всего содержимого каждого файла, открытого любым другим процессом.
В зависимости от уровня безопасности и необходимости такой передачи следует рассмотреть возможность отключения сканирования ClamAV при доступе на время выполнения передачи.