【问题标题】:How can I limit the cache used by copying so there is still memory available for other caches?如何限制复制使用的缓存,以便其他缓存仍有可用内存?
【发布时间】:2012-04-23 17:09:03
【问题描述】:

基本情况:

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

我的猜测:

我相信这可能是由于缓存。 Linux 决定丢弃有用的缓存(例如,KDE 4 膨胀、虚拟机磁盘、LibreOffice 二进制文件、Thunderbird 二进制文件等),而是用复制磁盘中的内容填充所有可用内存(总共 24 GB),这将只能读取一次,然后写入,不再使用。因此,每当我使用这些应用程序(或 KDE 4)时,都需要再次读取磁盘,并且再次从磁盘读取膨胀会导致事情冻结/打嗝。

由于缓存消失了,而且这些臃肿的应用程序需要大量缓存,这使得系统非常缓慢。

由于是USB,磁盘和磁盘控制器都不是瓶颈,所以使用ionice并不能让它更快。

我相信这是缓存,而不仅仅是主板太慢了,因为如果我停止复制所有内容,它仍然会运行一段时间不稳定,直到重新缓存所有内容。

如果我重新开始复制​​,它需要一分钟才能再次波涛汹涌。而且,我可以将它限制在 40 MB/s 左右,并且它再次运行得更快(不是因为它缓存了正确的东西,而是因为主板总线为系统磁盘提供了很多额外的带宽)。我可以完全接受主板的 I/O 能力被完全消耗(这是 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 上尝试过同样的事情,这反而会导致整个系统挂起。 ;)

澄清一下,我不是在问如何为“系统”腾出内存,而是为“缓存”腾出内存。我知道缓存内存会在需要时自动返回给系统,但我的问题是它没有保留用于缓存特定事物。

有没有办法告诉这些复制操作来限制内存使用,以便一些重要的东西保持缓存,因此任何减速都是正常磁盘使用的结果,而不是重新读取相同的常用文件?例如,是否有允许将每个进程/用户/文件系统的最大内存用作缓存/缓冲区的设置?

【问题讨论】:

  • 顺便说一句,我正在使用 rsync,并且有很多磁盘(目前一次 8 个)。有些是在本地传输的,有些是使用 USB 3.0 传输的。有些是通过 1Gbps 网络传输的。
  • 什么都不复制时:#free total used free shared buffers cached Mem: 24731556 24474096 257460 0 16478072 6342668 -/+ 缓冲区/缓存:1653356 23078200 交换:4194300 22564 4171736 .

标签: linux caching filesystems usb file-copying


【解决方案1】:

如果您使用普通的旧 cp,这是不可能的,但如果您愿意自己重新实现或修补它,在输入和输出文件上设置 posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE) 可能会有所帮助。

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

【讨论】:

    【解决方案2】:

    尝试使用dd 而不是cp

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

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

    【讨论】:

    • 根据我的经验,使用 rsync 总是一个好主意(没有 -u 选项会破坏一切)。如果没有,我将在传输中断时得到未检测到的部分文件。
    • 第一次尝试时,它在远程副本上不起作用,因为服务器不支持该选项。 (两者都有 rsync 版本 3.0.9 协议版本 30;Linux 支持它,但 FreeBSD 8.2 不支持)而且在本地传输上,它似乎限制了很多速度。
    • @Peter 是的,我通常会尽量避免dd 我忘了rsync...这么多实用程序:D
    • 在第二条评论之前插入此评论...以某种方式被删除:感谢您的建议。这使我阅读了 rsync 手册页,在其中我找到了“--drop-cache”选项,它实际上似乎适用于本地传输。
    • 看看另一个答案,你甚至可以加快同步速度。
    【解决方案3】:

    好的,现在我知道您使用的是rsync,我可以进一步挖掘:

    同时处理大量文件时,rsync 似乎无效。 their FAQ 中有一个条目,这不是 Linux/缓存问题。这是一个 rsync 问题,占用了太多 RAM。

    搜索someone recommended to split the syncing in multiple rsync invocations

    【讨论】:

    • 很好的信息,但我没有遇到任何内存不足的问题。我有 22032652 字节的空闲空间。这可能是因为我的这些文件大部分都是很多 GB 的。当 rsync 启动时,它会显示“要考虑的 18658 个文件”。当我有数以亿计的文件时,我也使用过它,它也可以工作。但是多亏了您的 dd 建议,并找到了 --drop-cache 选项,它实际上似乎已经完全解决了(只要我在服务器不支持 --drop-cache 时不进行太多远程传输) .
    【解决方案4】:

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

    减速是known memory management issue

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

    【讨论】:

    • 我正在使用带有内核 3.1.0-1.2-desktop 的 openSuSE。我不知道这是否适用;这个特定问题的症状是什么?
    • 有趣 - 但我对此状态感到困惑。在我看来,Mel Gorman 在 LWN 上讨论的补丁不在当前内核(3.13-rc5)中,我无法确定它在您引用的 LinuxChanges 页面上的地址。分辨率是多少,它出现在哪个内核中?谢谢。
    • @nealmcb 在 Linux 3.3 中已修复。 LinuxChanges 行是“与透明大页面相结合的压缩可能会导致 USB 记忆棒或浏览器严重停止。推荐 LWN article”。 [与此答案中链接的相同 LWN 文章]。
    • @nealmcb 或者我第一次发现它的地方:lore.kernel.org/lkml/…。与补丁 1-10 具有相同标题的提交被合并到 v3.3-rc1 中。你可以在这里的 github 界面中看到它们一起列出:github.com/torvalds/linux/commits/… 求职信说补丁 11 是“原型”,讨论听起来好像没有成功。我没有尝试深入研究那部分的细节。但总的来说,这似乎很有定论。
    【解决方案5】:

    Kristof Provost was very close,但在我的情况下,我不想使用dd 或编写自己的软件,所以解决方案是使用 rsync 中的“--drop-cache”选项。

    自从创建这个问题以来,我已经使用了很多次,它似乎完全解决了这个问题。一个例外是当我使用 rsync 从不支持“--drop-cache”的 FreeBSD 机器上进行复制时。所以我写了一个包装器来替换 /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
    

    【讨论】:

    • 官方rsync中没有drop-cache
    【解决方案6】:

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

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

    它对我来说也很好用,尤其是结合大量 RAM (16-32 GB) 时性能非常好。

    【讨论】:

      【解决方案7】:

      nocache 命令是这个问题的一般答案!它也在 Debian 和 Ubuntu 13.10 (Saucy Salamander) 中。

      感谢 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 等)和其他您不想破坏缓存的命令。

      【讨论】:

      • @Peter 我认为 nealmcb 的 'nocache' 答案更合适,因为并非所有 rsync 都有 drop-cache 选项,并且 nocache 使用更广泛
      • 从我的角度来看,我测试过的每个 Linux 发行版(除了 Manjaro,也不是 FreeBSD)都将补丁应用到 rsync...并且当我使用它时 nocache 不在 openSUSE 中,并且't 在 arch/manjaro 的主要存储库中。而且我更喜欢 nocache 的想法(就像我喜欢 nice、ionice、trickle 等一样),但除非我在更多的主要 repos 中看到它,否则它有点主观,对每个人来说都是最好的解决方案。
      • @Peter Debian 没有
      • @krzyk nocache 不在哪个 debian 中?看起来它在 wheezy-backports、jessie、stretch 和 sid 中​​:packages.debian.org/sid/utils/nocache
      • 我在回复@Peter 关于 --drop-cache in rsync
      【解决方案8】:

      您实际上有两个选择:

      1. 限制最大磁盘缓冲区大小:您看到的问题可能是由默认内核配置引起的对于一个非常慢的设备,您最终会占用大量宝贵的 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. 为要保持快速执行的每个任务保留最小内存大小。在实践中,这意味着为您关心的内容创建cgroups,并为任何此类组定义您希望拥有的最小内存。这样,内核可以根据需要使用 剩余 内存。有关详细信息,请参阅此演示文稿:SREcon19 Asia/Pacific - Linux Memory Management at Scale: Under the Hood

      【讨论】:

        猜你喜欢
        • 2010-09-26
        • 2013-05-22
        • 2010-10-16
        • 2012-11-10
        • 2012-12-12
        • 2019-12-30
        • 2014-08-14
        • 2015-07-21
        • 2015-02-07
        相关资源
        最近更新 更多