如何限制复制使用的缓存,以便仍有可用于其他缓存的内存?

时间:2012-04-11 11:42:15

标签: linux caching filesystems usb file-copying

基本情况:

我在openSuSE中复制一些NTFS磁盘。每个都是2TB。当我这样做时,系统运行缓慢。

我的猜测:

我认为这可能是由于缓存造成的。 Linux决定丢弃有用的缓存(例如kde4膨胀,虚拟机磁盘,LibreOffice二进制文件,Thunderbird二进制文件等),而是用复制磁盘中的东西填充所有可用内存(总共24 GB),这些内容只读一次,然后写,再也没用过。因此,每当我使用这些应用程序(或kde4)时,需要再次读取磁盘,并再次从磁盘读取膨胀使得事情冻结/打嗝。

由于缓存消失以及这些膨胀的应用程序需要大量缓存这一事实,这使得系统非常慢。

由于它是USB,因此磁盘和磁盘控制器不是瓶颈,因此使用ionice不会使它更快。

我认为这是缓存,而不仅仅是主板太慢,因为如果我停止所有复制,它仍会运行一段时间,直到它重新读取所有内容。如果我重新启动复制,它需要一分钟才能再次出现波动。但是,我可以将它限制在大约40 MB / s,并且它再次运行得更快(不是因为它具有正确的缓存,而是因为主板总线为系统磁盘提供了大量额外带宽)。我可以完全接受主板的IO功能被完全消耗的性能损失(100%使用,意味着0%的浪费功率让我开心),但我不能接受这种缓存机制在这个特定用途中表现如此糟糕情况下。

# free
             total       used       free     shared    buffers     cached
Mem:      24731556   24531876     199680          0    8834056   12998916
-/+ buffers/cache:    2698904   22032652
Swap:      4194300      24764    4169536

我也在Ubuntu上做了同样的事情,这导致整个系统挂起。 ;)

为了澄清,我不是要求如何为“系统”留出内存,而是为了“缓存”。我知道缓存内存会在需要时自动返回给系统,但我的问题是它不会保留用于缓存特定的东西。

问题:

有没有办法告诉这些复制操作限制内存使用,所以一些重要的事情仍然被缓存,因此任何减速是由于正常的磁盘使用而不重读相同的常用文件?例如,是否允许将每个进程/用户/文件系统的最大内存设置用作缓存/缓冲区?

8 个答案:

答案 0 :(得分:19)

nocache命令是这个问题的一般答案!请参阅https://github.com/Feh/nocache或在Debian和Ubuntu 13.10(俏皮)中找到它。

谢谢,Peter,提醒我们使用rsync中的--drop-cache“选项。但是这被拒绝上游(Bug 9560 – drop-cache option),支持更通用的解决方案:新的”nocache“基于rsync与fadvise一起工作的命令。

您只需将“nocache”添加到您想要的任何命令中。它还具有很好的实用程序,用于描述和修改文件的缓存状态。例如。这是有和没有nocache的效果:

$ ./cachestats ~/file.mp3
pages in cache: 154/1945 (7.9%)  [filesize=7776.2K, pagesize=4K]
$ ./nocache cp ~/file.mp3 /tmp
$ ./cachestats ~/file.mp3
pages in cache: 154/1945 (7.9%)  [filesize=7776.2K, pagesize=4K]\
$ cp ~/file.mp3 /tmp
$ ./cachestats ~/file.mp3
pages in cache: 1945/1945 (100.0%)  [filesize=7776.2K, pagesize=4K]

所以希望这适用于其他备份程序(rsnapshot,duplicity,rdiff-backup,amanda,s3sync,s3ql,tar等)以及其他不想丢弃缓存的命令。

答案 1 :(得分:3)

Kristof Provost非常接近,但在我的情况下,我不想使用dd或编写我自己的软件,因此解决方案是在rsync中使用“--drop-cache”选项。

自从创建这个问题以来,我已经多次使用它,它似乎完全解决了这个问题。一个例外是当我使用rsync从FreeBSD机器复制时,它不支持“--drop-cache”。所以我编写了一个包装器来替换/ usr / local / bin / rsync命令,并删除该选项,现在它也可以从那里进行复制。

它仍然为缓冲区使用了大量内存,并且似乎几乎没有缓存,但无论如何都能顺利运行。

$ free
             total       used       free     shared    buffers     cached
Mem:      24731544   24531576     199968          0   15349680     850624
-/+ buffers/cache:    8331272   16400272
Swap:      4194300     602648    3591652

答案 2 :(得分:1)

如果你使用的是普通的cp,那是不可能的,但如果你愿意重新实现或修补它,那么在输入和输出文件上设置posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE)可能会有所帮助。< / p>

posix_fadvise()告诉内核您的预期访问模式。在这种情况下,您只使用一次数据,因此缓存它没有意义。 Linux内核尊重这些标志,因此不应再缓存数据了。

答案 3 :(得分:1)

尝试使用dd代替cp

mount带有sync标记的文件系统。

我不完全确定这些方法是否绕过交换,但值得一试。

只是我的2c。

答案 4 :(得分:1)

  

我正在复制一些NTFS磁盘[...]系统运行缓慢。 [...]   因为它是USB [...]

减速是known memory management issue

使用较新的Linux内核。较旧的有USB数据和“透明大页面”的问题。见LWN article。最近这个问题已得到解决,请参阅LinuxChanges中的“内存管理”。

答案 5 :(得分:1)

内核无法知道,你不会再使用复制的缓存数据。这是您的信息优势。

但您可以将交换设置为0:sudo sysctl vm.swappiness = 0。这将导致linux在将库等写入交换之前删除缓存。

对我来说也很好用,特别是与hugh ram(16-32 GB)相结合非常高效。

答案 6 :(得分:0)

好的,现在我知道你使用rsync并且我可以挖掘更多:

似乎rsync在与大量文件同时使用时无效,在their FAQ中有一个条目,它不是linux / cache问题,这是一个rsync问题吃RAM太多了。

someone recommended to split the syncing in multiple rsync invocations

上搜索

希望它有所帮助。

答案 7 :(得分:0)

您实际上有两种选择:

  1. 限制最大磁盘缓冲区大小:您看到的问题可能是由默认内核配置引起的,该配置允许使用 巨大 块 RAM 用于磁盘缓冲,并且当您尝试写入时很多东西到一个非常慢的设备上,你最终会占用大量宝贵的 RAM 用于磁盘缓存,从而降低设备的速度。

    内核这样做是因为它假设进程在没有被慢速设备减慢时可以继续做一些事情,并且如果需要,只需将页面写入存储(慢速 USB 记忆棒 -但内核不考虑该进程的实际性能)。快速修复:

     # Wake up background writing process if there's more than 50 MB of dirty memory
     echo 50000000 > /proc/sys/vm/dirty_background_bytes
     # Limit background dirty bytes to 200 MB (source: http://serverfault.com/questions/126413/limit-linux-background-flush-dirty-pages)
     echo 200000000 > /proc/sys/vm/dirty_bytes
    

    调整数字以匹配您愿意在磁盘写入缓存上花费的 RAM。合理的值取决于您的实际写入性能,而不是您拥有的 RAM 量。您的目标应该是几乎没有足够的 RAM 用于缓存,以便为您的设备提供完整的写入性能。请注意,这是一个全局设置,因此您必须根据您使用的最慢设备进行设置。

  2. 为您希望保持快速运行的每个任务保留最小内存大小。实际上,这意味着为您关心的内容创建 cgroup 并定义您希望为任何此类组拥有的最小内存。这样,内核就可以使用它认为合适的剩余内存。有关详细信息,请参阅此演示文稿:SREcon19 Asia/Pacific - Linux Memory Management at Scale: Under the Hood