Rsync 在单个 50 GB 文件上触发 Linux OOM killer

Rsync 在单个 50 GB 文件上触发 Linux OOM killer

我在服务器 A 上有一个 50 GB 的文件,我正在将其复制到服务器 B。我运行

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

Server_B 有 32 GB 的 RAM 和 2 GB 的交换空间。它大部分时间处于闲置状态,应该有大量的可用 RAM。它有足够的磁盘空间。当 RAM 达到约 32 GB 时,传输会中止,因为远程端关闭了连接。

Server_B 现在已经断网。我们要求数据中心重新启动它。当我查看崩溃前的内核日志时,我发现它使用了 0 字节交换,进程列表使用了很少的内存(rsync 进程被列为使用了 600 KB 的 RAM),但 oom_killer 却在疯狂运行,日志中的最后一件事是它杀死了 metalog 的内核读取器进程。

这是内核 3.2.59,32 位(因此无论如何没有进程可以映射超过 4 GB)。

这几乎就像 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

以下是以非 root 用户身份重复我的 rsync 命令后的“top”输出:

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内存,即 4KB。

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_REPEATGFP_FSGFP_IO的标志GFP_WAIT,因此不是特别挑剔。

那么发生了什么ZONE_NORMAL?在 OOM 输出中可以找到一些通用统计数据:

[内核] [1772321.850770] 正常可用:8056kB 最小:8048kB 最低:10060kB高:12072kB 活跃匿名:0kB 非活跃匿名:0kB 活跃文件:248kB 非活跃文件:388kB 不可驱逐:0kB 隔离(匿名):0kB 隔离(文件):0kB 存在:890008kB

值得注意的是free距离仅 8​​Kmin以及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

基本上表明您有一个 4MB 的连续页面,其余页面主要分散在 4KB 大小的页面中。

让我们回顾一下:

  • 你有一个用户空间进程(clamd)从中获取内存ZONE_NORMAL,而非特权内存分配通常是从中执行的ZONE_HIMEM
  • 此时内存管理器应该能够提供请求的 4K 页面,尽管你似乎在ZONE_NORMAL
  • 系统按照kswapd其规则,应该之前已经看到了一些分页活动,但没有任何东西被换出,即使在内存压力下ZONE_NORMAL,也没有明显的原因
  • 以上都没有给出为什么oom-killer被援引的明确理由

所有这些看起来都很奇怪,但至少与John O'Gorman 的优秀著作《理解 Linux 虚拟内存管理器》第 2.5 节

由于内核可用的地址空间(ZONE_NORMAL)大小有限,因此内核支持高端内存的概念。[...] 为了访问 1GiB 到 4GiB 范围内的内存,内核使用 kmap() 将高端内存中的页面临时映射到 ZONE_NORMAL。[...]

这意味着描述 1GiB 内存需要大约 11MiB 的内核内存。因此,描述 16GiB 内存需要消耗 176MiB 内存,这给 ZONE_NORMAL 带来了巨大压力。这听起来还不算太糟,除非考虑使用 ZONE_NORMAL 的其他结构。即使是非常小的结构(例如页表条目 (PTE)),在最坏的情况下也需要大约 16MiB。这使得 16GiB 成为 x86 上 Linux 可用物理内存的实际限制

(重点是我的)

由于 3.2 在内存管理方面比 2.6 有了很大的进步,因此这不是一个明确的答案,但我首先要寻求的是一个非常强烈的暗示。通过使用内核参数mem=或从服务器中拆除一半的 DIMM,将主机的可用内存减少到最多 16G。

最终,使用 64 位内核

兄弟,现在是 2015 年了。

答案2

一些东西 ...

我的经验法则是,交换空间至少应为物理内存的 2 倍。这样,页面/交换守护进程就能够高效地重组内存。

Server_B 有 32GB 的内存,因此请尝试将其配置为 64GB 的交换空间。在我看来,您的服务器拥有的 2GB 交换空间方式太低了,尤其是对于服务器来说。

如果你没有多余的分区可以用作交换分区,你可以通过创建一个文件并将其挂载为交换分区来测试这一点 [这会很慢]。请参阅https://www.maketecheasier.com/swap-partitions-on-linux/

由于 server_B 有足够的磁盘空间,因此不需要 --inplace,并且可能不受欢迎,因为它可能是导致 rsync 使用 32GB 的原因。--inplace 仅在文件系统空间不足(而您不是)或有某些特殊性能要求时才真正有用。

我猜想 rsync 会使用 50GB 的内存(即文件大小)来执行您当前的选项。通常,rsync 不需要那么多内存来完成其工作,因此您的一个或多个选项可能是问题所在。我经常传输 200GB 的文件,没有任何问题。

不使用任何选项进行一些测试运行。使用较小的文件(例如 10GB)进行测试 - 这应该可以防止内核崩溃,但仍允许您监视导致问题的行为。监视 rsync 的内存使用情况。

逐渐地,一次添加一个选项,以查看哪个选项[或选项组合]导致rsync开始占用RAM(例如,在传输过程中,rsync的RAM使用量与传输的文件数据量成比例增长,等等)。

如果您确实需要导致 rsync 保留一些 RAM 文件映像的选项,那么您将需要额外的交换空间,并且您的最大文件大小将受到相应的限制。

另外几件事[更新]:

(1)内核堆栈回溯显示 rsync 在 mmap 区域发生页面错误。它可能正在对文件进行 mmap。mmap 无法保证它会刷新到磁盘直到文件被关闭[与读/写不同],它会立即进入文件系统块缓存[在那里它将被刷新]

(2) 当传输大小达到 RAM 大小时,会发生内核崩溃/崩溃。显然,rsync 通过 malloc 或 mmap 占用了那么多非 fscache 内存。再次,使用您指定的选项,rsync 将分配 50GB 内存来传输 50GB 的文件。

(3)传输一个 24GB 的文件。这应该可以。然后,使用 mem=16G 启动内核,并再次进行 24GB 文件测试。它会在 16GB 而不是 32GB 时溢出。这将确认 rsync 确实需要内存。

(4) 在您说添加交换空间是荒谬的之前,请尝试添加一些 [通过交换到文件的方法]。这比所有关于交换空间不需要的学术争论要容易得多。即使这不是解决方案,您也可以从中学到一些东西。我敢打赌,mem=16G 测试将成功,不会出现恐慌/崩溃。

(5)rsync 有可能达到交换,但发生得太快,在 OOM 启动并终止 rsync 之前,无法使用 top 看到。当 rsync 达到 32GB 时,其他进程已经被迫交换,特别是如果它们处于空闲状态。也许,“free”和“top”的组合会给你更好的画面。

(6) rsync 被终止后,需要花费一些时间将 mmap 刷新到 FS。速度不够快,无法达到 OOM 要求,因此它开始终止其他任务(其中一些任务显然至关重要)。也就是说,mmap 刷新和 OOM 正在竞争。或者,OOM 存在错误。否则,就不会发生崩溃。

(7) 根据我的经验,一旦系统“遇到内存瓶颈”,Linux 需要很长时间才能完全恢复。而且,有时它永远无法真正恢复正常,唯一的解决方法是重新启动。例如,我有 12GB 的 RAM。当我运行一个使用 40GB 内存的作业(我有 120GB 的交换空间来容纳大型作业)然后将其终止时,系统需要大约 10 分钟才能恢复正常响应(磁盘灯一直亮着)。

(8)运行 rsync没有选项。这将有效。获取一个基准示例。然后重新添加 --inplace 并重新测试。然后改为执行 --append-verify。然后,尝试两者。找出哪个选项让 rsync 执行巨大的 mmap。然后决定是否可以没有它。如果 --inplace 是罪魁祸首,那很容易理解,因为您有足够的磁盘空间。如果您必须有该选项,则必须获取交换空间以容纳 rsync 将执行的 malloc/mmap。

第二次更新:

请执行上面的 mem= 和较小的文件测试。

核心问题:为什么 rsync 会因为 OOM 而终止?谁/什么在消耗内存?

我读过 [但忘记了] 有关系统是 32 位的信息。因此,我同意,rsync 可能不直接负责(通过 malloc/mmap——glibc 通过匿名/私有 mmap 实现大型 malloc),并且 rsync 的 mmap 页面错误恰好触发了 OOM。然后,OOM 直接和间接计算 rsync 消耗的总内存 [FS 缓存、套接字缓冲区等],并决定它是主要候选者。因此,监控总内存使用情况可能会有所帮助。我怀疑它以与文件传输相同的速度增长。显然,它不应该。

您可以通过快速循环中的 perl 或 python 脚本来监控 /proc 或 /proc/rsync_pid 中的某些内容 [bash 脚本可能不够快,无法处理世界末日事件],该脚本可以每秒监控以下所有事件数百次。您可以以比 rsync 更高的优先级运行它,这样它就会保持在 RAM 中并运行,这样您就可以在崩溃之前监控事物,并希望在 OOM 期间监控事物,这样您就可以了解 OOM 为何会失控:

/proc/meminfo——在“影响点”获取有关交换使用情况的更细粒度信息。实际上,获取总共使用了多少 RAM 的最终数字可能更有用。虽然 top 提供了这一点,但它可能不够快,无法显示“大爆炸”之前宇宙的状态(例如最后 10 毫秒)

/proc/rsync_pid/fd 目录。读取符号链接将允许您识别在目标文件上打开了哪个 fd(例如 /proc/rsync_pid/fd/5 --> target_file 的 readlink)。这可能只需要执行一次即可获取 fd 编号 [它应该保持固定]

知道 fd 编号后,查看 /proc/rsync_pid/fdinfo/fd。这是一个文本文件,如下所示:

pos: <文件位置>
标志:blah_blah
mnt_id:blah_blah

监控“pos”值可能会有所帮助,因为“最后文件位置”可能很有用。如果您使用不同的大小和 mem= 选项进行多次测试,最后文件位置是否会跟踪其中任何一个 [以及如何]?通常的怀疑是:文件位置 == 可用 RAM

但是,最简单的方法是从“rsync local_file server:remote_file”开始,然后验证它是否有效。通过执行“ssh server rsync file_a file_b”,您可能能够获得类似 [但更快] 的结果 [您需要先创建一个 50GB 的 file_a]。创建 file_a 的一种简单方法是 scp local_system:original_file server:file_a,这本身可能很有趣(例如,当 rsync 崩溃时,这是否有效?如果 scp 有效,但 rsync 失败,则指向 rsync。如果 scp 失败,则指向其他东西,例如 NIC 驱动程序)。执行 ssh rsync 还会将 NIC 排除在外,这可能会有所帮助。如果这会使系统陷入困境,那么确实出了问题。如果成功,[正如我所提到的] 开始逐一添加选项。

我不想过多地强调这一点,但通过交换到文件添加一些交换可能会改变/延迟崩溃行为,并且可能作为诊断工具很有用。如果添加 16GB 的交换可以将崩溃(以内存使用量或目标文件位置衡量)从 32GB 延迟到 46GB,那么这将说明一些问题。

它可能不是某个特定进程,而是一个错误的内核驱动程序正在占用内存。内核的内部 vmalloc 分配内容,并且可以将其交换出去。如果我没记错的话,它在任何情况下都不受寻址能力的约束。

显然,OOM 变得混乱/恐慌。也就是说,它杀死了 rsync,但没有及时看到内存释放,于是开始寻找其他受害者。其中一些可能对系统运行至关重要。

除了 malloc/mmap 之外,这可能是由于未刷新的 FS 缓存需要很长时间(例如,对于 30GB 的未刷新数据,假设磁盘速率为 300 MB/秒,刷新可能需要 100 秒)。即使以这样的速率,OOM 也可能太不耐烦了。或者,OOM 终止 rsync 不会足够快地启动 FS 刷新(或根本不启动)。或者 FS 刷新发生得足够快,但它会“懒惰地”将页面释放回空闲池。您可以设置一些 /proc 选项来控制 FS 缓存行为(我不记得它们是什么了)。

尝试使用 mem=4G 或其他较小的数字进行启动。这可能会减少 FS 缓存并缩短其刷新时间,以防止 OOM 寻找其他要终止的东西(例如刷新时间从 100 秒减少到 < 1 秒)。它还可能揭示无法在 32 位系统或类似系统上处理物理内存 > 4GB 的 OOM 错误。

另外,还有一点很重要:以非 root 身份运行。root 用户永远不需要消耗资源,因此他们被给予了更宽松的限制(例如,99% 的内存,而非 root 用户为 95%)。这也许可以解释为什么 OOM 处于这种状态。此外,这为 OOM 等提供了更多的空间来完成回收内存的工作。

答案3

clamd?听起来你正在使用 ClamAV,并且启用了访问时扫描,防病毒引擎会尝试扫描打开的文件中是否存在病毒,将任何其他进程打开的每个文件的全部内容加载到内存中

根据您的安全状况和此传输的必要性,您应该评估在执行传输时禁用 ClamAV 按访问扫描。

相关内容