25

基本情况:

我在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 上尝试过同样的事情,这会导致整个系统挂起。;)

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

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

4

8 回答 8

27

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

感谢 Peter 提醒我们注意 rsync 中的 --drop-cache" 选项。但这在上游被拒绝了(错误 9560 – drop-cache option),支持更通用的解决方案:新的“nocache”命令基于 fadvise 的 rsync 工作。

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

于 2013-12-28T18:16:06.597 回答
3

Kristof Provost 非常接近,但在我的情况下,我不想使用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
于 2012-05-10T13:33:09.027 回答
2

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

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

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

于 2012-12-31T14:38:18.680 回答
1

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

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

于 2012-04-11T12:06:44.443 回答
1

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

减速是一个已知的内存管理问题

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

于 2012-04-11T17:26:41.047 回答
1

尝试使用dd而不是cp.

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

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

于 2012-04-11T12:10:40.433 回答
1

您实际上有两种选择:

  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为您关心的内容创建 s 并定义您希望为任何此类组拥有的最小内存。这样,内核可以根据需要使用剩余的内存。有关详细信息,请参阅此演示文稿:SREcon19 Asia/Pacific - Linux Memory Management at Scale: Under the Hood

于 2021-01-04T09:27:47.673 回答
0

好的,既然我知道您正在使用rsync,我可以再挖掘一下:

rsync 似乎在同时与大量文件一起使用时无效。他们的 FAQ中有一个条目,这不是 Linux/缓存问题。这是一个吃太多 RAM 的 rsync 问题。

谷歌搜索有人建议将同步拆分为多个rsync调用

于 2012-04-11T12:54:09.283 回答