Rsync викликав вбивцю Linux OOM в одному файлі об'ємом 50 Гб


66

У мене є один файл 50 Гб на сервері_А, і я копіюю його на сервер_В. я біжу

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 був задихається, і останнє, що входить у журнал, - це вбивання процесу зчитування ядра металога.

Це ядро ​​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

Ось результат "верхній" після повторення моєї команди 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

Ось параметри vm sysctl:

# 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
Я не знаю читання повідомлень про збої ядра, але я не можу побачити жодних ознак того, що B використовував 32 ГБ ядра. Перш ніж перейти до припущення, що це було, чи можете ви підтвердити, що це зараз? Тому що велика різниця між вичерпною пам'яттю коробкою з 32 ГБ ядра та такою, що має лише 4 ГБ.
MadHatter

Оновлено Топ виводу. Це після запуску тієї самої команди rsync, як і некореневий користувач. Зараз майже все, крім 1 Гб, використовується для кешу.
даних

Дякую. Як я вже сказав, я не експерт - але це здавалося вартим перевірки.
MadHatter

Ви також повинні переконатися, що ваше ядро ​​дозволяє замінити (тобто, заміна не вимкнена) (і вам слід виділити більший фрагмент дискового простору, скажімо, 16Gb або навіть 32Gb). Деякі дивні люди в мережі рекомендують вимкнути заміну, що дуже неправильно.
Олів'є Дулак

@OlivierDulac, про яке налаштування ви посилаєтесь? Підтримка swap збирається в або ми не зможемо встановити swap, а "swappiness" встановлено на 60. Що стосується розміру swap, чи не погіршить це проблему на 32-бітному ядрі? З'являється відповідь, що нас вбили структури даних ядра. У нас не працює 32 ГБ користувачів, ми просто хочемо стільки оперативної пам’яті для кеш-диску, для продуктивності.
даних

Відповіді:


178

Тож давайте прочитаємо висновок про убивцю, і дізнаємося, що можна дізнатися звідти.

Аналізуючи журнали вбивць OOM, важливо подивитися, що це викликало. Перший рядок вашого журналу дає нам деякі підказки:

[kernel] [1772321.850644] clamd викликав oom-killer: gfp_mask = 0x84d0, order = 0

order=0говорить нам, скільки пам'яті запитується. Управління пам'яттю ядра вміє керувати лише номерами сторінок потужністю 2, тому clamd запитав 2 0 сторінки пам'яті або 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

У вашому випадку маска зони дорівнює 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 ММ , так що ваш requst має прапори GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOі GFP_WAIT, таким чином , будучи не особливо прискіпливі.

То що з цим ZONE_NORMAL? Деякі загальні статистичні дані можна знайти далі у висновку OOM:

[kernel] [1772321.850770] Нормальний вільний: 8056kB хв: 8048kB низький: 10060kB високий: 12072kB active_anon: 0kB inactive_anon: 0kB active_file: 248kB inactive_file: 388kB unvictable: 0kB ізольований (anon): 0kB ізольований (файл): 0kB ізольований (файл)

Помітно тут те, що freeце всього 8K від minта дорога під low. Це означає, що менеджер пам’яті вашого хоста дещо переживає проблему, і kswapd повинен замінювати сторінки вже так, як це знаходиться у жовтій фазі графіку нижче: Графік менеджера пам'яті Linux

Більше інформації про фрагментацію пам'яті зони наведено тут:

[ядро] [1772321.850795] Нормально: 830 * 4kB 80 * 8kB 0 * 16kB 0 * 32kB 0 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 1 * 4096kB = 8056kB

в основному заявляючи, що у вас є одна суміжна сторінка розміром 4 Мб, а решта сильно фрагментована в основному на 4 КБ сторінок.

Тож давайте переглянемо:

  • у вас є процес користувальницької роботи ( clamd) отримання пам'яті, ZONE_NORMALтоді як непривілейоване розподіл пам'яті зазвичай виконується зZONE_HIMEM
  • на цьому етапі менеджер пам'яті повинен був мати можливість обслуговувати запитувану 4K сторінку, хоча, здається, у вас є великий тиск пам'яті ZONE_NORMAL
  • система, за kswapdправилами, повинна була заздалегідь побачити певну активність пейджингу, але нічого не змінюється, навіть під тиском пам'яті ZONE_NORMAL, без видимих ​​причин
  • Жодне з перерахованого вище не дає чіткої причини, чому саме oom-killerбуло викликано

Все це здається дивним, але принаймні має бути пов'язане з тим, що описано в розділі 2.5 чудової книги Джона О'Гормана "Розуміння диспетчера віртуальної пам'яті Linux" :

Оскільки простір адрес, використовуваний ядром (ZONE_NORMAL), має обмежений розмір, ядро ​​підтримує концепцію високої пам'яті. [...] Щоб отримати доступ до пам'яті між діапазоном 1GiB і 4GiB, ядро ​​тимчасово відображає сторінки з високої пам'яті в ZONE_NORMAL за допомогою kmap (). [...]

Це означає, що для опису пам'яті 1GiB потрібно приблизно 11MiB пам'яті ядра. Таким чином, при 16GiB споживається 176MiB пам'яті, що чинить значний тиск на ZONE_NORMAL. Це не здається занадто поганим, поки не будуть враховані інші структури, які використовують ZONE_NORMAL. Навіть дуже маленькі структури, такі як записи в табличну сторінку (PTE), вимагають приблизно 16MiB в гіршому випадку. Це робить 16GiB приблизно практичним обмеженням доступної фізичної пам'яті Linux на x86 .

(акцент мій)

Оскільки 3.2 має численні досягнення в управлінні пам’яттю понад 2,6, це не є однозначною відповіддю, а справді сильним підказом, якого я б переслідував першим. Зменшіть корисну пам'ять хоста до максимум 16G, використовуючи mem=параметр ядра або витягнувши половину DIMM з сервера.

Зрештою, використовуйте 64-розрядне ядро .

Чувак, це 2015 рік.


13
Коли я сказав вище " я не експерт ", це те, що я сподівався прочитати. +1000, якщо я міг, але міг; +1 точно. Яка чудова відповідь!
MadHatter

18
Це було красиво. Є ще надія на СФ.
Роман

9
@dataless Так. Я підозрюю, що всі ваші ZONE_NORMAL заповнені метаданими про верхні регіони пам'яті. Коли процес користувальницького запиту запитує сторінки пам'яті, він, швидше за все, збирається запитувати ZONE_HIGHMEM (який може бути оновлений MM до ZONE_NORMAL, якщо HIGHMEM не має більше вільних сторінок для обслуговування запиту, але NORMAL має), тому, якщо ZONE_HIGHMEM знаходиться під тиском пам'яті (у вас немає), ZONE_NORMAL не матиме сторінок процесів у просторі користувачів.
the wabbit

3
[ударить кулаками по клавіатурі] Надайте цьому вабіту щедрість
підкреслити

3
@ the-wabbit Гарячі питання мережі.
CodesInChaos

4

Кілька речей ...

Моє правило для розміщення місця заміни полягало у тому, щоб мати принаймні 2 рази кількість фізичного барана. Це дає можливість демону сторінок / поміняти можливість ефективної реорганізації пам'яті.

Server_B має 32 ГБ оперативної пам’яті, тому спробуйте налаштувати його на 64 Гб свопу. ІМО, 2 Гб простору підкачки ваш сервер є шлях надто низькою, особливо для сервера.

Якщо у вас немає додаткового розділу, який ви можете перетворити в розділ swap, ви можете протестувати це, створивши файл і встановивши його як розділ swap [це буде повільно]. Дивіться https://www.maketecheasier.com/swap-partitions-on-linux/

Оскільки server_B має достатньо місця на диску, --місце не потрібне, і може бути небажаним, оскільки це може спричинити використання rsync 32 Гб. --inplace справді корисний лише у тому випадку, якщо вам не вистачає простору файлової системи [якого ви не є] або маєте якісь особливі вимоги до продуктивності.

Я здогадуюсь, що rsync захоче використовувати 50 ГБ оперативної пам’яті [розмір файлу] з вашими поточними параметрами. Зазвичай rsync не потребує стільки пам’яті, щоб виконати свою роботу, тому один або кілька ваших варіантів можуть бути проблемою. Я безперервно передаю файли 200 ГБ без проблем.

Зробіть кілька тестових запусків, не використовуючи жодних параметрів. Зробіть це з меншими файлами, скажімо, 10 Гб - це повинно запобігти паніці ядра, але все ж дозволять стежити за поведінкою, яка викликає проблему. Контролюйте використання пам'яті rsync.

Поступово додайте параметри зворотного зв’язку, по одному, щоб побачити, який варіант [або комбінація параметрів] змушує rsync починати викид на RAM (наприклад, поки відбувається передача, використання оперативної пам’яті rsync зростає пропорційно кількості переданих файлових даних, тощо).

Якщо вам справді потрібні параметри, які викликають rsync для збереження деякого вбудованого зображення файлу, вам знадобиться додаткове місце для обміну, і ваш максимальний розмір файлу буде відповідно обмежений.

Ще кілька речей [ОНОВЛЕНО]:

(1) Відстеження стека ядра показує, що rsync сталася помилкою сторінки в області mmap. Це, ймовірно, копіювання файлу. mmap не дає гарантії, що він буде переповнюватися на диск, поки файл не буде закритий [на відміну від читання / запису], який відразу ж перейде до кешу блоку FS [там, де він буде розмитий]

(2) Збій / паніка ядра відбувається, коли розмір передачі досягає розміру ОЗУ. Очевидно, що rsync захоплює стільки пам'яті, яка не є fscache, за допомогою malloc або mmap. Ще раз, із вказаними вами параметрами, rsync виділить 50 Гб пам'яті для передачі файлу 50 Гб.

(3) Передайте файл 24 ГБ. Це, мабуть, спрацює. Потім завантажте ядро ​​з mem = 16G і повторіть тест на 24 ГБ файлу. Він вибухне на 16 Гб, а не на 32 ГБ. Це підтвердить, що rsync дійсно потребує пам'яті.

(4) Перш ніж сказати, що додавати своп смішно, спробуйте додати деякі [методом підкачки до файлу]. Це зробити набагато простіше і перевірити, ніж усі академічні аргументи щодо того, як своп не потрібен. Навіть якщо це не рішення, ви можете щось з цього навчитися. Б'юсь об заклад, що тест mem = 16G вдасться без паніки / аварії.

(5) Швидше за все , що Rsync буде вдаряти підкачки, але це відбувається занадто швидко , щоб побачити зверху , перш ніж OOM стусани в і вбиває Rsync. До того часу, коли rsync дістанеться до 32 ГБ, інші процеси вже вимушені міняти місцями, особливо якщо вони не працюють. Можливо, поєднання "вільного" та "вершини" дасть вам кращу картину.

(6) Після того, як rsync буде вбита, потрібен час, щоб передати mmap до FS. Недостатньо швидкий для ООМ, і він починає вбивати інші речі [деякі, очевидно, критично важливі]. Тобто, mmap flush і OOM мчаться. Або в OOM є помилка. Інакше не буде аварії.

(7) На мій досвід, як тільки система "потрапляє на стіну пам'яті", Linux потребує тривалого часу, щоб повністю відновитися. І, іноді він ніколи не реалізується належним чином, і єдиний спосіб очистити це перезавантаження. Наприклад, у мене є 12 ГБ оперативної пам’яті. Коли я запускаю роботу, яка використовує 40 Гб пам'яті [у мене є 120 Гб своп для розміщення великих робочих місць], а потім вбиваю її, потрібно приблизно 10 хвилин, щоб система повернулася до нормальної чутливості [з індикатором диска увімкнено весь час] .

(8) Запустити rsync без параметрів. Це спрацює. Отримайте базовий приклад для роботи. Потім додайте назад - замініть і перевірте. Потім замість цього зробіть --append-verify. Потім спробуйте обидва. Дізнайтеся, який варіант отримує rsync, роблячи величезну mmap. Тоді вирішіть, чи можете ви жити без цього. Якщо виною винуватцем --inplace, це не марення, оскільки у вас є багато місця на диску. Якщо у вас є така опція, вам доведеться отримати місце для заміни для розміщення malloc / mmap, що буде виконувати rsync.

ДРУГЕ ОНОВЛЕННЯ:

Будь ласка, зробіть mem = та менші тести файлів із зазначеного вище.

Основні питання: Чому rsync вбивається OOM? Хто / що жує пам’ять?

Я прочитав [але забув] про те, що система є 32-бітовою. Отже, я погоджуюся, rsync може не нести пряму відповідальність (через malloc / mmap - glibc реалізує великі малики через анонімні / приватні mmaps), а помилка сторінки mmap rsync просто запускає OOM за збігом обставин. Потім OOM обчислює загальну пам'ять, споживану rsync безпосередньо та опосередковано [кеш-пам'ять FS, буфери сокет тощо) та вирішує, що це головний кандидат. Отже, моніторинг загального використання пам'яті може бути корисним. Я підозрюю, що вона повзає з тією ж швидкістю, що і передача файлів. Очевидно, це не повинно.

Деякі речі, які ви можете відстежувати в / proc або / proc / rsync_pid за допомогою сценарію perl або python у швидкому циклі [сценарій bash, ймовірно, не буде досить швидким для події кінця світу], який може контролювати всіх наступні кілька сотень разів / сек. Ви можете запустити це з більш високим пріоритетом, ніж rsync, так що він буде тримати себе в оперативній пам’яті та працює, щоб ви могли відстежувати речі безпосередньо перед збоєм і, сподіваємось, під час роботи OOM, щоб ви могли зрозуміти, чому OOM сходить з розуму:

/ proc / meminfo - щоб отримати більше дрібного зерна при використанні свопів у "точці удару". Насправді, отримати остаточне число за загальною кількістю оперативної пам’яті може бути кориснішим. У той час як вершина забезпечує це, це може бути недостатньо швидким, щоб показати стан Всесвіту безпосередньо перед "великим ударом" (наприклад, останні 10 мілісекунд)

/ proc / каталог / rsync_pid / fd. Читання символьних посилань дозволить визначити, який fd відкритий у цільовому файлі (наприклад, посилання для читання / proc / rsync_pid / fd / 5 -> target_file). Це, мабуть, потрібно зробити лише один раз, щоб отримати номер fd [він повинен залишатися фіксованим]

Знаючи номер fd, подивіться на / proc / rsync_pid / fdinfo / fd. Це текстовий файл, який виглядає так:

pos: <файл_позиція>
прапори: blah_blah
mnt_id: blah_blah

Моніторинг значення "pos" може бути корисним, оскільки "остання позиція файлу" може бути корисною. Якщо ви робите кілька тестів з різними розмірами та параметрами mem =, чи відстежує остання позиція файлу будь-яку з цих [і як]? Звичайний підозрюваний: позиція файлу == доступна оперативна пам'ять

Але найпростіший спосіб - почати з "rsync local_file server: remote_file" і перевірити, чи працює він. Можливо, ви зможете отримати подібні [але швидші] результати, зробивши "ssh server rsync file_a file_b" [спочатку вам потрібно буде створити файл 50 Гб ". Простий спосіб створення file_a - це scp local_system: original_file сервер: file_a, і це може бути цікаво самому собі (наприклад, чи працює це, коли rsync виходить з ладу? Якщо scp працює, але rsync виходить з ладу, це вказує на rsync. Якщо scp виходить з ладу, це вказує до чогось іншого, як драйвер NIC). Виконання ssh rsync також виводить NIC з рівняння, що може бути корисним. Якщо це шланг системи, то щось насправді не так. Якщо це вдасться, [як я вже згадував] починайте додавати назад варіанти один за одним.

Я ненавиджу сприймати точку, але додавання певного свопу через swap-to-файл може змінити / затримати поведінку аварії та може бути корисним як діагностичний інструмент. Якщо додавання, скажімо, 16 Гб, заміни затримує збій [як вимірюється використанням пам'яті або цільовим розташуванням файлу] від 32 ГБ до 46 ГБ, то це щось скаже.

Це може бути не якийсь конкретний процес, але помилковий драйвер ядра, який жує пам'ять. Внутрішній vmalloc ядра виділяє матеріал, і його можна замінити. IIRC, адреса не пов'язана за будь-яких обставин.

Зрозуміло, що OOM заплутується / панікує. Тобто, вона вбиває rsync, але не бачить пам'яті, яка звільняється вчасно, і йде на пошуки інших жертв. Деякі з них, ймовірно, є критичними для роботи системи.

malloc / mmap вбік, це може бути викликано незапущеним кеш-пам'яттю FS, який займає тривалий час (наприклад, при 30 Гб необроблених даних, якщо припускати швидкість диска 300 Мб / с, це може зайняти 100 секунд, щоб його промити). Навіть при такому темпі ОМВ може бути занадто нетерплячим. Або OOM, що вбиває rsync, не запускає FS блискавки досить швидко [або взагалі]. Або FS-флеш відбувається досить швидко, але він має "ледачий" випуск сторінок назад у вільний пул. Існують деякі параметри / proc, які можна встановити для керування поведінкою кешу FS [я не пам'ятаю, що вони].

Спробуйте завантажуватися з mem = 4G або іншим невеликим числом. Це може скоротити кеш-пам'ять FS і скоротити час його змивання, щоб утримувати OOM від пошуку інших речей (наприклад, час змиву скорочується зі 100 сек до <1 сек). Він також може розкрити помилку OOM, яка не може обробити фізичний оперативної пам'яті> 4 Гб у 32-бітовій системі чи іншому подібному.

Також важливий момент: запустити як некоріозний. Користувачі корінців ніколи не жуватимуть ресурси, тому їм надаються більш прості обмеження (наприклад, 99% пам'яті проти 95% для некоріальних користувачів). Це може пояснити, чому ООМ знаходиться в такому стані. Також це дає OOM et. ін. більше приміщення для того, щоб зробити свою роботу по відновленню пам'яті.


Подивіться, скільки простору SWAP у системі високої пам’яті? - і ви не хочете, щоб ваша система використовувала 63 Гб свопу. Він не буде корисним.
Мартін Шредер

1
swap> ОЗУ дуже корисний лише в тому випадку, якщо ви запускаєте без перезавантаження VM, тому ядру потрібно зарезервувати місця для розміщення виділених сторінок, поки вони не забруднені та не потребують реальних фізичних сторінок, що їх підтримують. Сучасна практика полягає в тому, щоб дозволити перевиконання та запускати з невеликою кількістю місця для розміщення сторінок, які розкривали сторінки, які торкнулися лише під час запуску і не потрібні в звичайній роботі. overcommit = 0 з невеликим свопом - добре, якщо у вас багато оперативної пам’яті, для більшості систем.
Пітер Кордес

Виявляється , що Rsync дійсно буде намагатися використовувати> 32GB, тому заміна для цього необхідно. Тобто, rsync використовуватиме 50 Гб для цього файлу. 2x був випробуваним і справжнім показником протягом 30 років. Оскільки диск на 6 ТБ становить ~ 300 доларів, немає причини цього не робити. Що ще може працювати на цьому сервері, що в сукупності пересуватиме обмеження оперативної пам’яті?
Крейг Есті

1
@CraigEstey 64 Гб свопу є абсолютно смішним, оскільки, як я вже говорив раніше, у нас немає великих процесів користувача, нам потрібен лише кеш-диск, і, як показав мій журнал, ми використовували ZAPO swap під час аварії. ZERO. Також rsync використовує 600 КБ оперативної пам’яті навіть у файлі об'ємом 50 Гб. Моя початкова плутанина полягала в тому, що, можливо, Linux агресивно тримався на кеш-диску. І нарешті, я хочу ознайомитись з деякими номерами або документацією про те, скільки пам'яті використовує ядро ​​для відстеження свого місця обміну, перш ніж я додам більше до цього вікна.
даних

@dataless Я додав додаткову інформацію, яка повністю пояснює, що відбувається і чому. Rsync буде вистачати пам'яті через Танос / ттар , і він буде йти на 50GB , перш ніж це зробити. Дивіться оновлений розділ. У ньому є тести, які можуть довести / спростувати те, що я кажу, і ви можете пропустити доданий своп спочатку, щоб перевірити. До речі, я програмував KERNELS / драйверів для 40+ років - я міг би тільки знати що - то , що ви цього не зробите, тому , будь ласка , стримати тон - я буду намагатися допомогти.
Крейг Есті

2

затискати? Це здається, що ви використовуєте ClamAV та увімкнено сканування під час доступу, коли антивірусна програма намагається сканувати відкриті файли на віруси, завантажуючи в пам'ять весь вміст кожного файлу, відкритого будь-яким іншим процесом .

Залежно від постави безпеки та необхідності цієї передачі, слід оцінити відключення сканування під час доступу ClamAV під час виконання передачі.


Я не знав, що це навіть річ, яку можуть зробити clamav ... але ні, ми скануємо лише специфічні файли, перекладені на неї з clamc. Крім того, 32-розрядний, так що немає небезпеки, щоб clamav вивісив всю системну пам'ять. (Ви бачите, чому ми думали, що 32-розрядна все ще гарна ідея?)
даних

1
Ядро Linux повідомляє, що clamd - це процес, запити якого на розподіл пам'яті викликають вбивцю OOM - ClamAV майже напевно є вторинною причиною (первинною причиною є недостатня кількість пам'яті). Будь то сканування під час доступу чи інша конфігурація, всі знаки вказують на ClamAV.
оо.

Наступного разу, коли ви запускаєте rsync, запустіть зверху та стежте за розміром резидента процесу clamd.
оо.

clamd був першим процесом, який викликав убивцю oom, але також першим, хто загинув, оскільки він важить майже в 42 Мб (один з великих процесів на сервері). Після цього oom_killer повторюється, поки навіть металог не вбивається.
даних
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.