Rsync在单个50 GB文件上触发了Linux OOM杀手


66

我在server_A上只有一个50 GB的文件,并将其复制到server_B。我跑

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

Server_B具有32 GB的RAM和2 GB的交换空间。它大部分是空闲的,应该有很多可用的RAM。它具有足够的磁盘空间。由于远程端已关闭连接,因此传输中止大约为32 GB。

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

这是32位内核3.2.59(因此,任何进程都不能映射超过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

2
我不是读取内核崩溃消息的专家,但是我看不到任何迹象表明B正在使用32GB内核。在我们假设是以前之前,您可以确认它当前是吗?因为用尽32GB内核的盒子和仅4GB内核的盒子之间存在很大的差异。
MadHatter

更新为Top输出。这是在以非root用户身份运行相同的rsync命令之后。目前,除了1GB以外,几乎所有的空间都用于缓存。
2015年

谢谢。正如我所说,我不是专家-但这似乎值得检查。
MadHatter

您还应该验证内核是否允许交换(即未关闭交换)(并且您应该占用更大的磁盘空间,例如16Gb甚至32Gb)。网上有些怪异的人建议关闭交换,这是非常错误的。
Olivier Dulac

@OlivierDulac您指的是什么设置?交换支持已编译进来,否则我们将无法挂载交换,并且'swappiness'设置为60。至于交换大小,是否会在32位内核上使问题变得更糟?答案似乎是内核数据结构使我们丧命。我们没有运行32GB的用户进程,我们只是想要那么多的RAM用于磁盘缓存和性能。
2015年

Answers:


178

因此,让我们阅读oom-killer的输出,看看可以从中学到什么。

分析OOM杀手日志时,重要的是要查看触发它的原因。您的日志的第一行为我们提供了一些线索:

[内核] [1772321.850644]蛤invoke调用了oom-killer:gfp_mask = 0x84d0,order = 0

order=0告诉我们正在请求多少内存。内核的内存管理只能管理2的幂的页码,因此clamd请求了2 0页内存或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文件,所以您requst具有标志为GFP_ZEROGFP_REPEATGFP_FSGFP_IOGFP_WAIT,因此是不是特别挑剔。

那怎么了ZONE_NORMAL?在OOM输出中可​​以找到一些常规统计信息:

[内核] [1772321.850770]正常空闲时间:8056kB分钟:8048kB低位:10060kB高位:12072kB active_anon:0kB inactive_anon:0kB active_file:248kB inactive_file:388kB unvictable:0kB孤立的(anon):0kB孤立的(文件):0kB存在:890008kB

值得注意的是,free距离min下方仅8K 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的页面。

因此,让我们概括一下:

  • 您有一个userland进程(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年。


13
当我在上面说“ 我不是专家 ”时,就是我希望阅读的内容。+1000,如果可以的话;肯定+1。真是个好答案!
MadHatter

18
真漂亮 旧金山仍然有希望。
罗马

9
@dataless是的。我怀疑您的所有ZONE_NORMAL都充满了有关高端内存区域的元数据。当userland进程正在请求内存页面时,它很可能会请求ZONE_HIGHMEM(如果HIGHMEM没有更多的空闲页面可用于请求,而NORMAL则有MM将其升级到ZONE_NORMAL),除非ZONE_HIGHMEM处于内存压力下(您的不是),ZONE_NORMAL将没有用户空间进程的页面。
the-wabbit

3
[键盘上的猛拳]给这个兔子带来赏金
underscore_d

3
@ the-wabbit热门网络问题。
CodesInChaos

4

一些东西 ...

我对交换空间的经验法则是至少有2倍的物理内存。这使页面/交换守护程序能够有效地重组内存。

Server_B具有32GB的内存,因此请尝试将其配置为64GB的交换空间。IMO,服务器所具有的交换空间为2GB 方式太低了,特别是对于一个服务器。

如果您没有可以划分为交换分区的额外分区,则可以通过创建文件并将其安装为交换分区来进行测试(这会很慢)。参见https://www.maketecheasier.com/swap-partitions-on-linux/

由于server_B具有足够的磁盘空间,因此不需要--inplace,并且可能不希望使用--inplace,因为这可能导致rsync使用32GB。--inplace仅在文件系统空间不足(不是)或有一些特殊的性能要求时才真正有用。

我的猜测是rsync将要在当前选项中使用50GB的ram [文件大小]。通常,rsync不需要那么多的内存来完成其工作,因此您的一个或多个选项可能是问题所在。我例行地传输200GB文件没有问题。

不使用任何选项进行一些测试运行。使用较小的文件(例如10GB)执行此操作,这应该可以防止内核崩溃,但是仍然可以监视引起问题的行为。监视rsync的内存使用情况。

逐步添加一次选项,以查看哪个选项[或选项组合]导致rsync开始在RAM上输出(例如,在进行传输时,rsync的ram使用率与传输的文件数据量成正比,等等。)。

如果您确实需要使rsync保留一些内存中文件映像的选项,则将需要额外的交换空间,并且相应的最大文件大小将受到限制。

还有几件事[更新]:

(1)内核堆栈回溯显示rsync在mmap区域发生页面错误。它可能正在映射文件。mmap无法保证在文件关闭之前将其刷新到磁盘(与读/写不同),该文件会立即进入FS块缓存[将在其中刷新]

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

(3)传输24GB文件。那可能会起作用。然后,以mem = 16G引导内核并再次进行24GB文件测试。它将以16GB而不是32GB的容量爆炸。这将确认rsync确实需要内存。

(4)在您说添加交换是荒谬的之前,尝试添加一些[通过swap-to-file方法]。这比所有关于不需要交换的学术观点都容易进行和测试。即使不是解决方案,您也可以从中学到一些东西。我敢打赌,mem = 16G测试将成功而不会出现紧急情况/崩溃。

(5)很有可能rsync 发生了交换,但是在OOM介入并杀死rsync之前,出现这种情况的速度太快了。到rsync达到32GB时,其他进程已经被迫交换,特别是在它们空闲的时候。也许,“免费”和“顶级”的组合会给您带来更好的印象。

(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通过匿名/私有mmaps实现大型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:<file_position>
标志:blah_blah
mnt_id:blah_blah

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

但是,最简单的方法是从“ rsync local_file server:remote_file”开始并验证其是否有效。通过执行“ ssh服务器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分配了内容,可以将其换出。IIRC,在任何情况下都不受可寻址性的约束。

显然,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等。等 有更多的余地来执行其回收内存的工作。


请参阅高内存系统上有多少SWAP空间?-并且您不希望您的系统使用63GB的交换空间。它将无法使用。
MartinSchröder2015年

1
swap> RAM仅在没有VM过量使用的情况下才真正有用,因此内核需要为分配的页面保留交换空间,直到它们被弄脏并需要实际的物理页面来支持它们。当前的做法是允许过量使用,并使用少量交换空间运行以换出仅在启动时触及而在正常操作中不需要的页面。如果您有很多RAM,则对于大多数系统,使用少量交换的overcommit = 0很好。
彼得·科德斯

看来rsync确实尝试使用> 32GB,因此需要进行交换。也就是说,rsync将为此文件使用50GB.2倍已成为30年来的可靠指标。由于6TB磁盘的价格约为300美元,因此没有理由不这样做。该服务器上可能还运行了哪些其他操作,这些操作将共同推动RAM限制?
Craig Estey 2015年

1
@CraigEstey 64 GB的交换完全荒谬,因为正如我之前所说,我们没有大型的用户进程,我们只需要磁盘缓存,并且正如我的日志所示,崩溃时我们使用的是零交换。零。即使在50GB的文件上,rsync也会使用600KB的ram。我最初的困惑是,也许linux积极地保留了磁盘缓存。最后,在向此框添加更多内容之前,我想了解一些有关内核用于跟踪交换空间的内存的数字或文档。
2015年

@dataless我添加了其他信息,这些信息完全说明正在发生的事情以及原因。rsync的抓住通过的malloc / MMAP内存和它做的时候,才去50GB。请参阅更新的部分。它的测试可以证明/反驳我在说什么,您可以最初跳过添加的掉期进行测试。顺便说一句,我已经对内核/驱动程序进行了40多年的编程-我可能只知道您不了解的内容,所以请保持一定的语调-我正在尝试提供帮助。
Craig Estey 2015年

2

lam?听起来您正在使用ClamAV,并且启用了按访问扫描,在该扫描中,防病毒引擎尝试通过将其他进程打开的每个文件的全部内容加载到内存中,来扫描打开的文件中是否存在病毒。

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


我什至不知道clamav可以做到这一点……但是,不,我们只扫描clamc传给它的特定文件。此外,它是32位的,因此不会出现clamav占用所有系统内存的危险。(您知道为什么我们认为32位仍然是个好主意吗?)
无数据

1
Linux内核报告clamd是其内存分配请求正在调用OOM杀手的进程-ClamAV几乎可以肯定是次要原因(主要原因是内存不足)。无论是按访问扫描还是其他配置,所有迹象都指向ClamAV。
哦。

下次启动rsync时,请运行top并监视clamd进程的驻留大小。
哦。

clamd是第一个调用oom killer的进程,但也是第一个死于它的进程,因为它的大小约为42MB(服务器上较大的进程之一)。oom_killer在此之后重复运行,直到连metalog被杀死。
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.