Rsync kích hoạt trình diệt OOM Linux trên một tệp 50 GB


66

Tôi có một tệp 50 GB trên server_A và tôi đang sao chép nó vào server_B. tôi chạy

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

Server_B có 32 GB RAM với 2 GB trao đổi. Nó chủ yếu là không sử dụng và cần có nhiều RAM miễn phí. Nó có nhiều không gian đĩa. Ở mức khoảng 32 GB, việc chuyển tiền bị hủy vì phía từ xa đã đóng kết nối.

Server_B hiện đã ngừng hoạt động. Chúng tôi yêu cầu trung tâm dữ liệu khởi động lại nó. Khi tôi nhìn vào nhật ký kernel từ trước khi nó bị sập, tôi thấy rằng nó đang sử dụng 0 byte trao đổi và danh sách quy trình sử dụng rất ít bộ nhớ (quá trình rsync được liệt kê là sử dụng 600 KB RAM), nhưng oom_killer là trở nên hoang dã, và điều cuối cùng trong nhật ký là nơi nó giết chết quá trình đọc kernel của metalog.

Đây là kernel 3.2.59, 32 bit (vì vậy không có quá trình nào có thể ánh xạ hơn 4 GB).

Gần như là Linux ưu tiên cho bộ nhớ đệm hơn là các trình nền chạy lâu dài. Đưa cái gì?? Và làm thế nào tôi có thể ngăn chặn nó xảy ra một lần nữa?

Đây là đầu ra của 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

Đây là đầu ra 'trên cùng' sau khi lặp lại lệnh rsync của tôi với tư cách là người dùng không 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

Dưới đây là các tham số 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
Tôi không phải là chuyên gia về đọc các thông báo sự cố hạt nhân, nhưng tôi không thể thấy bất kỳ dấu hiệu nào cho thấy B đang sử dụng 32GB lõi. Trước khi chúng tôi tiến hành giả định rằng đó là, bạn có thể xác nhận rằng nó hiện tại không? Bởi vì có một sự khác biệt lớn giữa việc làm cạn kiệt bộ nhớ với một hộp có 32GB lõi và một hộp chỉ có 4GB.
MadHatter

Cập nhật với đầu ra hàng đầu. Đây là sau khi chạy lệnh rsync tương tự như một người dùng không root. Khá nhiều tất cả nhưng 1GB được sử dụng cho bộ nhớ cache ngay bây giờ.
dataless

Cảm ơn. Như tôi đã nói, tôi không phải là chuyên gia - nhưng có vẻ như đáng để kiểm tra.
MadHatter

bạn cũng nên xác minh rằng kernel của bạn không cho phép hoán đổi (nghĩa là trao đổi không bị tắt) (và bạn nên dành một phần lớn hơn của không gian đĩa, giả sử 16Gb hoặc thậm chí 32Gb). Một số người kỳ lạ trên mạng khuyên bạn nên tắt trao đổi, điều này rất sai.
Olivier Dulac

@OlivierDulac bạn đang đề cập đến cài đặt nào? hỗ trợ trao đổi được biên dịch trong hoặc chúng tôi sẽ không thể gắn kết trao đổi và 'swappiness' được đặt thành 60. Đối với kích thước trao đổi, điều đó có làm cho vấn đề trở nên tồi tệ hơn, trên kernel 32 bit không? Câu trả lời xuất hiện rằng cấu trúc dữ liệu kernel là thứ đã giết chúng tôi. Chúng tôi không chạy 32GB quy trình người dùng, chúng tôi chỉ muốn có nhiều ram cho bộ đệm đĩa, cho hiệu suất.
dataless

Câu trả lời:


178

Vì vậy, chúng ta hãy đọc đầu ra oom-killer và xem những gì có thể học được từ đó.

Khi phân tích nhật ký sát thủ OOM, điều quan trọng là phải xem xét điều gì đã kích hoạt nó. Dòng đầu tiên của nhật ký của bạn cung cấp cho chúng tôi một số manh mối:

[kernel] [1772321.850644] clamd đã gọi oom-killer: gfp_mask = 0x84d0, order = 0

order=0đang cho chúng tôi biết bao nhiêu bộ nhớ đang được yêu cầu. Quản lý bộ nhớ của kernel chỉ có thể quản lý số trang theo quyền hạn của 2, vì vậy clamd đã yêu cầu 2 0 trang bộ nhớ hoặc 4KB.

Hai bit thấp nhất của GFP_MASK (lấy mặt nạ trang miễn phí) tạo thành cái gọi là mặt nạ vùng cho người cấp phát biết vùng nào sẽ lấy bộ nhớ từ :

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

Vùng nhớ là một khái niệm được tạo ra chủ yếu vì lý do tương thích. Trong chế độ xem đơn giản, có ba vùng cho Hạt nhân 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

Trong trường hợp của bạn, zonemask là 0, có nghĩa là clamd đang yêu cầu bộ nhớ từ ZONE_NORMAL.

Các cờ khác đang giải quyết

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

theo tài liệu Linux MM , vì vậy requst của bạn có những lá cờ cho GFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOGFP_WAIT, như vậy là không đặc biệt kén cá chọn canh.

Vì vậy, những gì với ZONE_NORMAL? Một số số liệu thống kê chung có thể được tìm thấy thêm trong đầu ra OOM:

[kernel] [1772321.850770] Bình thường miễn phí: 8056kB phút: 8048kB thấp: 10060kB cao: 12072kB active_anon: 0KB inactive_anon: 0KB active_file: 248kB inactive_file: 388kB unevictable: 0KB bọc cách điện (anon): 0KB cô lập (file): 0KB hiện: 890008kB

Đáng chú ý ở đây là freechỉ 8K từ minvà cách dưới low. Điều này có nghĩa là trình quản lý bộ nhớ của máy chủ của bạn đang gặp sự cố và kswapd nên hoán đổi các trang đã có trong giai đoạn màu vàng của biểu đồ bên dưới: Biểu đồ quản lý bộ nhớ Linux

Một số thông tin khác về sự phân mảnh bộ nhớ của vùng được đưa ra ở đây:

[kernel] [1772321.850795] Bình thường: 830 * 4kB 80 * 8kB 0 * 16kB 0 * 32kB 0 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 1 * 4096kB = 8056

về cơ bản nói rằng bạn có một trang 4 MB liền kề với phần còn lại bị phân mảnh nhiều thành các trang 4KB.

Vì vậy, hãy tóm tắt lại:

  • bạn có một quy trình người dùng ( clamd) nhận bộ nhớ ZONE_NORMALtrong khi phân bổ bộ nhớ không đặc quyền thường sẽ được thực hiện từZONE_HIMEM
  • Trình quản lý bộ nhớ ở giai đoạn này đã có thể phục vụ trang 4K được yêu cầu, mặc dù bạn dường như có áp lực bộ nhớ đáng kể trong ZONE_NORMAL
  • theo kswapdquy tắc của hệ thống, đáng lẽ phải thấy một số hoạt động phân trang trước đó, nhưng không có gì bị tráo đổi, ngay cả dưới áp lực bộ nhớ ZONE_NORMAL, mà không có nguyên nhân rõ ràng
  • Không có điều nào ở trên đưa ra một lý do xác định như lý do tại sao oom-killerđã được viện dẫn

Tất cả những điều này có vẻ khá kỳ lạ, nhưng ít nhất là có liên quan đến những gì được mô tả trong phần 2.5 của cuốn sách "Tìm hiểu về Trình quản lý bộ nhớ ảo Linux" tuyệt vời của John O'Gorman :

Vì không gian địa chỉ có thể sử dụng bởi kernel (ZONE_NORMAL) bị giới hạn về kích thước, kernel có hỗ trợ cho khái niệm High Memory. [...] Để truy cập bộ nhớ trong phạm vi 1GiB và 4GiB, hạt nhân tạm thời ánh xạ các trang từ bộ nhớ cao vào ZONE_NORMAL với kmap (). [...]

Điều đó có nghĩa là để mô tả 1GiB bộ nhớ, cần khoảng 11MiB bộ nhớ kernel. Do đó, với 16GiB, 176MiB bộ nhớ được tiêu thụ, gây áp lực đáng kể cho ZONE_NORMAL. Điều này không có vẻ quá tệ cho đến khi các cấu trúc khác được đưa vào tài khoản sử dụng ZONE_NORMAL. Ngay cả các cấu trúc rất nhỏ như Mục nhập bảng trang (PTE) yêu cầu khoảng 16MiB trong trường hợp xấu nhất. Điều này tạo ra 16GiB về giới hạn thực tế cho bộ nhớ vật lý Linux có sẵn trên x86 .

(nhấn mạnh là của tôi)

Vì 3.2 có nhiều tiến bộ trong quản lý bộ nhớ trên 2.6, đây không phải là một câu trả lời chắc chắn, nhưng là một gợi ý thực sự mạnh mẽ mà tôi sẽ theo đuổi trước tiên. Giảm bộ nhớ có thể sử dụng của máy chủ xuống tối đa 16G bằng cách sử dụng mem=tham số kernel hoặc bằng cách trích xuất một nửa số DIMM ra khỏi máy chủ.

Cuối cùng, sử dụng Kernel 64 bit .

Anh bạn, đó là 2015.


13
Khi tôi nói ở trên " Tôi không phải là chuyên gia ", đây là những gì tôi đã hy vọng đọc được. +1000, nếu tôi nhưng có thể; +1 chắc chắn. Thật là một câu trả lời tuyệt vời!
MadHatter

18
Điều đó thật đẹp. Vẫn còn hy vọng cho SF.
La Mã

9
@dirthess Vâng. Tôi nghi ngờ rằng tất cả ZONE_NORMAL của bạn chứa đầy siêu dữ liệu về các vùng bộ nhớ phía trên. Khi một quy trình người dùng đang yêu cầu các trang bộ nhớ, rất có thể nó sẽ yêu cầu ZONE_HIGHMEM (có thể được MM nâng cấp lên ZONE_NORMAL nếu HIGHMEM không có nhiều trang miễn phí hơn để phục vụ yêu cầu nhưng BÌNH THƯỜNG có) (không phải của bạn), ZONE_NORMAL sẽ không có trang quy trình không gian người dùng.
the-wợi

3
[đóng sầm nắm đấm trên bàn phím] Cung cấp cho tiền thưởng này
underscore_d

3
@ the-wmus Câu hỏi mạng nóng.
CodeInChaos

4

Một vài thứ ...

Quy tắc ngón tay cái của tôi cho không gian hoán đổi đã có ít nhất gấp đôi lượng ram vật lý. Điều này cho phép trang / trao đổi daemon khả năng sắp xếp lại bộ nhớ hiệu quả.

Server_B có 32GB ram, vì vậy hãy thử định cấu hình cho 64GB trao đổi. IMO, 2GB không gian trao đổi máy chủ của bạn có là cách quá thấp, nhất là đối với một máy chủ.

Nếu bạn không có phân vùng bổ sung mà bạn có thể tạo thành phân vùng trao đổi, bạn có thể kiểm tra điều này bằng cách tạo tệp và gắn nó làm phân vùng trao đổi [nó sẽ chậm]. Xem https://www.maketecheasier.com/swap-partitions-on-linux/

Vì server_B có nhiều dung lượng đĩa, không cần thiết - và có thể không mong muốn vì đó có thể là nguyên nhân khiến rsync sử dụng 32GB. --inplace chỉ thực sự hữu ích nếu bạn thiếu không gian hệ thống tập tin [mà bạn không] hoặc có một số yêu cầu hiệu suất đặc biệt.

Tôi đoán là rsync sẽ muốn sử dụng 50GB ram [kích thước tệp] với các tùy chọn hiện tại của bạn. Thông thường, rsync không cần nhiều bộ nhớ để thực hiện công việc của mình, vì vậy một hoặc nhiều tùy chọn của bạn có thể là vấn đề. Tôi thường xuyên chuyển các tập tin 200GB mà không gặp vấn đề gì.

Thực hiện một số lần chạy thử không sử dụng tùy chọn. Làm điều này với các tệp nhỏ hơn, giả sử là 10 GB - điều này sẽ ngăn chặn sự hoảng loạn của kernel, nhưng vẫn cho phép bạn theo dõi hành vi gây ra sự cố. Theo dõi việc sử dụng bộ nhớ của rsync.

Dần dần, thêm các tùy chọn quay lại, từng tùy chọn một lần, để xem tùy chọn nào [hoặc kết hợp các tùy chọn] khiến rsync bắt đầu tiết kiệm RAM (ví dụ: trong khi quá trình truyền đang diễn ra, việc sử dụng ram của rsync tăng tỷ lệ thuận với lượng dữ liệu tệp được truyền, Vân vân.).

Nếu bạn thực sự cần các tùy chọn khiến rsync giữ một số hình ảnh tệp trong ram, bạn sẽ cần thêm không gian hoán đổi và kích thước tệp tối đa của bạn sẽ bị giới hạn tương ứng.

Một vài điều nữa [CẬP NHẬT]:

(1) Truy nguyên ngăn xếp kernel cho thấy rsync bị lỗi trang trên vùng mmap. Nó có thể là mmaping tập tin. mmap không đảm bảo rằng nó sẽ tuôn ra đĩa cho đến khi tệp được đóng [không giống như đọc / ghi] đi vào bộ đệm của khối FS ngay lập tức [nơi nó sẽ bị xóa]

(2) Sự cố / hoảng loạn hạt nhân xảy ra khi kích thước truyền đạt kích thước của RAM. Rõ ràng rsync đang chiếm được nhiều bộ nhớ không phải fscache thông qua malloc hoặc mmap. Một lần nữa, với các tùy chọn bạn đã chỉ định, rsync sẽ phân bổ 50GB bộ nhớ để truyền tệp 50 GB.

(3) Chuyển tập tin 24GB. Điều đó có thể sẽ làm việc. Sau đó, khởi động kernel với mem = 16G và thực hiện kiểm tra tệp 24GB một lần nữa. Nó sẽ thổi ra ở mức 16 GB thay vì 32 GB. Điều này sẽ xác nhận rằng rsync thực sự cần bộ nhớ.

(4) Trước khi bạn nói rằng việc thêm trao đổi là vô lý, hãy thử thêm một số [thông qua phương thức hoán đổi thành tập tin]. Điều này dễ thực hiện và kiểm tra hơn nhiều so với tất cả các lập luận học thuật về cách trao đổi không bắt buộc. Ngay cả khi đó không phải là giải pháp, bạn có thể học được điều gì đó từ nó. Tôi sẽ đặt cược rằng bài kiểm tra mem = 16G sẽ thành công mà không gặp sự cố / hoảng loạn.

(5) Rất có thể rsync đang trao đổi, nhưng nó xảy ra quá nhanh để nhìn thấy hàng đầu trước khi OOM khởi động và giết chết rsync. Vào thời điểm rsync đạt 32GB, các quy trình khác đã bị buộc phải trao đổi, đặc biệt nếu chúng không hoạt động. Có lẽ, sự kết hợp giữa "miễn phí" và "hàng đầu" sẽ cho bạn một bức tranh đẹp hơn.

(6) Sau khi rsync bị giết, cần có thời gian để tuôn ra mmap cho FS. Không đủ nhanh cho OOM và nó bắt đầu giết chết những thứ khác [một số rõ ràng là nhiệm vụ quan trọng]. Đó là, mmap tuôn ra và OOM đang chạy đua. Hoặc, OOM có một lỗi. Nếu không, sẽ không có một vụ tai nạn.

(7) Theo kinh nghiệm của tôi, một khi hệ thống "chạm vào tường nhớ", Linux phải mất một thời gian dài để khôi phục hoàn toàn. Và, đôi khi nó không bao giờ thực sự phục hồi đúng cách và cách duy nhất để xóa nó là khởi động lại. Ví dụ, tôi có 12GB RAM. Khi tôi chạy một công việc sử dụng 40GB bộ nhớ [Tôi có 120GB trao đổi để phù hợp với các công việc lớn] và sau đó giết nó, phải mất khoảng 10 phút để hệ thống trở lại phản hồi bình thường [với đèn luôn sáng] .

(8) Chạy rsync mà không có tùy chọn. Điều này sẽ làm việc. Lấy một ví dụ cơ bản để làm việc từ. Sau đó thêm lại - tại chỗ và kiểm tra lại. Sau đó, làm --append-verify thay thế. Sau đó, thử cả hai. Tìm hiểu tùy chọn nào được rsync thực hiện mmap lớn. Sau đó quyết định nếu bạn có thể sống mà không có nó. Nếu - nơi đó là thủ phạm, đó là điều không tưởng, vì bạn có nhiều không gian đĩa. Nếu bạn phải có tùy chọn, bạn sẽ phải có không gian hoán đổi để chứa malloc / mmap mà rsync sẽ làm.

CẬP NHẬT THỨ HAI:

Vui lòng thực hiện các bài kiểm tra mem = và nhỏ hơn từ phía trên.

Các câu hỏi chính: Tại sao rsync bị OOM giết? Ai / Bộ nhớ nhai là gì?

Tôi đọc [nhưng quên] về hệ thống là 32 bit. Vì vậy, tôi đồng ý, rsync có thể không chịu trách nhiệm trực tiếp (thông qua malloc / mmap - glibc thực hiện mallocs lớn thông qua mmaps ẩn danh / riêng tư) và lỗi trang mmap của rsync chỉ gây ra OOM do sự trùng hợp. Sau đó, OOM tính toán tổng bộ nhớ được tiêu thụ bởi rsync trực tiếp và gián tiếp [Bộ đệm FS, bộ đệm ổ cắm, v.v.] và quyết định đó là ứng cử viên chính. Vì vậy, giám sát tổng sử dụng bộ nhớ có thể hữu ích. Tôi nghi ngờ nó leo lên với tốc độ tương tự như việc chuyển tập tin. Rõ ràng là không nên.

Một số điều bạn có thể theo dõi trong / Proc hoặc / Proc / rsync_pid thông qua tập lệnh perl hoặc python trong một vòng lặp nhanh [tập lệnh bash có thể sẽ không đủ nhanh cho sự kiện cuối thế giới] có thể giám sát tất cả vài trăm lần sau / giây. Bạn có thể chạy cái này với mức độ ưu tiên cao hơn rsync để nó sẽ giữ RAM và chạy để bạn có thể theo dõi mọi thứ ngay trước khi gặp sự cố và hy vọng trong OOM để bạn có thể thấy tại sao OOM phát điên:

/ Proc / meminfo - để có được nhiều chi tiết tốt hơn trong việc sử dụng trao đổi tại "điểm tác động". Trên thực tế, việc lấy số cuối cùng về tổng số RAM đang được sử dụng có thể hữu ích hơn. Mặc dù top cung cấp điều này, nhưng nó có thể không đủ nhanh để hiển thị trạng thái của vũ trụ ngay trước "vụ nổ lớn" (ví dụ 10 mili giây cuối cùng)

thư mục / Proc / rsync_pid / fd. Đọc các liên kết tượng trưng sẽ cho phép bạn xác định fd nào được mở trên tệp đích (ví dụ: đường dẫn đọc của / Proc / rsync_pid / fd / 5 -> target_file). Điều này có lẽ chỉ cần được thực hiện một lần để có được số fd [nó sẽ được giữ cố định]

Biết số fd, hãy xem / Proc / rsync_pid / fdinfo / fd. Đó là một tệp văn bản trông giống như:

pos: <file_poseition>
cờ: blah_blah
mnt_id: blah_blah

Theo dõi giá trị "pos" có thể hữu ích vì "vị trí tệp cuối cùng" có thể hữu ích. Nếu bạn thực hiện một số thử nghiệm với các kích thước và tùy chọn mem = khác nhau, vị trí tệp cuối cùng có theo dõi bất kỳ trong số này [và cách thức] không? Nghi ngờ thông thường: vị trí tệp == RAM có sẵn

Nhưng, cách đơn giản nhất là bắt đầu với "rsync local_file server: remote_file" và xác minh rằng nó hoạt động. Bạn có thể nhận được kết quả tương tự [nhưng nhanh hơn] bằng cách thực hiện "ssh server rsync file_a file_b" [trước tiên bạn cần tạo tệp 50GB_a]. Một cách đơn giản để tạo file_a là scp local_system: original_file server: file_a và điều này có thể thú vị với chính nó (ví dụ: nó có hoạt động khi rsync gặp sự cố không? Nếu scp hoạt động, nhưng rsync không thành công đến một cái gì đó khác như trình điều khiển NIC). Thực hiện rsync ssh cũng đưa NIC ra khỏi phương trình, điều này có thể hữu ích. Nếu điều đó làm hỏng hệ thống, thì có gì đó thực sự sai. Nếu thành công, [như tôi đã đề cập] bắt đầu thêm lại các tùy chọn một.

Tôi ghét phải tin vào quan điểm, nhưng thêm một số trao đổi thông qua hoán đổi thành tập tin có thể thay đổi / trì hoãn hành vi sự cố và có thể hữu ích như một công cụ chẩn đoán. Nếu thêm, giả sử 16 GB, hoán đổi sẽ trì hoãn sự cố [như được đo bằng mức sử dụng bộ nhớ hoặc vị trí tệp mục tiêu] từ 32 GB đến 46 GB, thì điều đó sẽ nói lên điều gì đó.

Nó có thể không phải là bất kỳ quá trình cụ thể, nhưng một trình điều khiển hạt nhân sai lầm đang nhai bộ nhớ. Vmalloc nội bộ của kernel phân bổ công cụ và nó có thể được hoán đổi. IIRC, nó không bị ràng buộc bởi địa chỉ trong mọi trường hợp.

Rõ ràng, OOM đang bị lẫn lộn / hoảng loạn. Đó là, nó giết rsync, nhưng không thấy bộ nhớ được giải phóng kịp thời và đi tìm những nạn nhân khác. Một số trong số họ có thể rất quan trọng để vận hành hệ thống.

Bỏ qua malloc / mmap, điều này có thể do bộ đệm FS chưa được xử lý mất nhiều thời gian (ví dụ: với 30 GB dữ liệu không được lưu, giả sử tốc độ ổ đĩa là 300 MB / giây, có thể mất 100 giây để xóa nó). Ngay cả với tốc độ đó, OOM có thể quá nôn nóng. Hoặc, OOM giết rsync không bắt đầu tuôn ra FS đủ nhanh [hoặc hoàn toàn]. Hoặc việc xả FS xảy ra đủ nhanh, nhưng nó có một bản phát hành "lười biếng" trở lại nhóm miễn phí. Có một số tùy chọn / Proc bạn có thể đặt để kiểm soát hành vi bộ đệm của FS [Tôi không thể nhớ chúng là gì].

Hãy thử khởi động với mem = 4G hoặc một số số nhỏ khác. Điều này có thể cắt giảm bộ đệm của FS và rút ngắn thời gian xả của nó để ngăn OOM tìm kiếm những thứ khác để giết (ví dụ: thời gian xả giảm từ 100 giây xuống <1 giây). Nó cũng có thể vạch mặt một lỗi OOM không thể xử lý ram vật lý> 4GB trên hệ thống 32 bit hoặc một số thứ khác.

Ngoài ra, một điểm quan trọng: Chạy như không root. Người dùng root không bao giờ được dự kiến ​​sẽ nhai tài nguyên, vì vậy họ được đưa ra nhiều giới hạn tha thứ hơn (ví dụ 99% bộ nhớ so với 95% cho người dùng không root). Điều này có thể giải thích tại sao OOM ở trong tình trạng như vậy. Ngoài ra, điều này mang lại cho OOM et. al. thêm khoảng trống để thực hiện công việc lấy lại bộ nhớ.


Xem bao nhiêu dung lượng SWAP trên hệ thống bộ nhớ cao? - và bạn không muốn thấy hệ thống của mình sử dụng 63GB trao đổi. Nó sẽ không thể sử dụng được.
Tái lập Monica - M. Schröder

1
hoán đổi> RAM chỉ thực sự hữu ích nếu bạn chạy mà không cần VM overcommit, vì vậy kernel cần dành không gian trao đổi cho các trang được phân bổ cho đến khi chúng bị bẩn và cần các trang vật lý thực sự sao lưu chúng. Thực tiễn hiện tại là cho phép vượt mức và chạy với một lượng nhỏ không gian hoán đổi để thoát ra khỏi các trang chỉ được chạm khi khởi động và không cần thiết trong hoạt động bình thường. overcommit = 0 với trao đổi nhỏ là tốt nếu bạn có nhiều RAM, đối với hầu hết các hệ thống.
Peter Cordes

Dường như rsync thực sự đang cố gắng sử dụng> 32GB, vì vậy việc trao đổi là cần thiết cho điều đó. Đó là, rsync sẽ sử dụng 50GB cho tệp này. 2x đã là một số liệu thử và đúng trong 30 năm. Vì đĩa 6TB là ~ 300 đô la, không có lý do gì để không. Những gì khác có thể đang chạy trên máy chủ này mà tập thể sẽ vượt quá giới hạn RAM?
Craig Estey

1
@CraigEstey 64 GB trao đổi là hoàn toàn vô lý vì như tôi đã nói trước đó, chúng tôi không có quy trình người dùng lớn, chúng tôi chỉ muốn bộ đệm đĩa và như nhật ký của tôi cho thấy, chúng tôi đã sử dụng trao đổi ZERO tại thời điểm xảy ra sự cố. SỐ KHÔNG. Ngoài ra rsync sử dụng 600KB ram ngay cả trên tệp 50 GB. Sự nhầm lẫn ban đầu của tôi là có lẽ linux đang cố giữ bộ nhớ cache trên đĩa. Và cuối cùng, tôi muốn xem một số con số hoặc tài liệu về lượng bộ nhớ mà kernel sử dụng để theo dõi không gian hoán đổi của nó trước khi tôi thêm bất kỳ bộ nhớ nào vào hộp này.
dataless

@dirthess Tôi đã thêm thông tin bổ sung giải thích đầy đủ những gì đang xảy ra và tại sao. rsync đang lấy bộ nhớ thông qua malloc / mmap và nó sẽ có giá 50 GB trước khi hoàn thành. Xem phần cập nhật. Nó có các bài kiểm tra có thể chứng minh / từ chối những gì tôi đang nói và bạn có thể bỏ qua phần trao đổi được thêm vào ban đầu để kiểm tra. BTW, tôi đã lập trình hạt nhân / trình điều khiển trong hơn 40 năm - Tôi có thể chỉ biết một số thứ mà bạn không biết, vì vậy hãy kiểm duyệt giọng điệu - Tôi đang cố gắng giúp đỡ.
Craig Estey

2

ngao? Có vẻ như bạn đang sử dụng ClamAV và đã bật chức năng quét truy cập khi công cụ chống vi-rút cố gắng quét các tệp đã mở để tìm vi-rút, bằng cách tải vào bộ nhớ, toàn bộ nội dung của mọi tệp được mở bởi bất kỳ quy trình nào khác .

Tùy thuộc vào tư thế bảo mật của bạn và sự cần thiết của việc chuyển tiền này, bạn nên đánh giá việc vô hiệu hóa chức năng quét truy cập ClamAV trong khi bạn thực hiện chuyển tiền.


Tôi đã không biết đây thậm chí là một điều mà clamav có thể làm ... nhưng không, chúng tôi chỉ quét các tệp cụ thể được lấy từ clamc. Ngoài ra, 32-bit, do đó, không có nguy cơ clamav ăn cắp tất cả bộ nhớ hệ thống. (bạn thấy lý do tại sao chúng tôi nghĩ rằng 32-bit vẫn là một ý tưởng tốt?)
dataless

1
Nhân Linux đang báo cáo rằng clamd là quá trình mà các yêu cầu cấp phát bộ nhớ của nó đang gọi trình diệt OOM - ClamAV gần như chắc chắn là nguyên nhân thứ yếu (nguyên nhân chính là không đủ bộ nhớ). Cho dù đó là quét truy cập hoặc một số cấu hình khác, tất cả các dấu hiệu đều chỉ đến ClamAV.
oo.

Lần tới khi bạn bắt đầu rsync, hãy chạy trên cùng và theo dõi kích thước lưu trú của quy trình clamd.
oo.

clamd là quá trình đầu tiên để gọi kẻ giết người oom, nhưng cũng là người đầu tiên chết vì nó nặng gần 42 MB (một trong những tiến trình lớn hơn trên máy chủ). Oom_killer chạy liên tục sau đó cho đến khi thậm chí metalog bị giết.
dataless
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.