作为进行一些冷缓存计时的一部分,我正在尝试释放操作系统缓存。该内核文档(检索2019日)说:
drop_caches
Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes. Once dropped, their
memory becomes free.
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
echo 3 > /proc/sys/vm/drop_caches
This is a non-destructive operation and will not free any dirty objects.
To increase the number of objects freed …
Run Code Online (Sandbox Code Playgroud) 有没有办法告诉 Linux 内核只将一定比例的内存用于缓冲区缓存?我知道/proc/sys/vm/drop_caches
可以用来临时清除缓存,但是否有任何永久设置可以防止它增长到超过主内存的 50%?
我想这样做的原因是,我有一台运行 Ceph OSD 的服务器,它不断地从磁盘提供数据,并设法在几个小时内用完整个物理内存作为缓冲区缓存。同时,我需要运行将分配大量(数十 GB)物理内存的应用程序。与流行的看法相反(请参阅关于几乎所有有关缓冲区缓存的问题的建议),通过丢弃干净的缓存条目来自动释放内存不是即时的:当缓冲区缓存已满时,启动我的应用程序可能需要长达一分钟的时间( *),而在清除缓存后(使用echo 3 > /proc/sys/vm/drop_caches
),相同的应用程序几乎立即启动。
(*) 根据 Vtune 在一个名为pageblock_pfn_to_page
. 这个功能似乎与查找大页面所需的内存压缩有关,这让我相信实际上是碎片化的问题。
我如何描述或解释输出中的“缓冲区” free
?
$ free -h
total used free shared buff/cache available
Mem: 501M 146M 19M 9.7M 335M 331M
Swap: 1.0G 85M 938M
$ free -w -h
total used free shared buffers cache available
Mem: 501M 146M 19M 9.7M 155M 180M 331M
Swap: 1.0G 85M 938M
Run Code Online (Sandbox Code Playgroud)
我对这个系统没有任何(已知的)问题。我只是惊讶和好奇地看到“缓冲区”几乎和“缓存”一样高(155M vs 180M)。我认为“缓存”代表文件内容的页面缓存,并且往往是“缓存/缓冲区”中最重要的部分。我不确定什么是“缓冲区”。
例如,我将其与具有更多 RAM 的笔记本电脑进行了比较。在我的笔记本电脑上,“缓冲区”数字比“缓存”小一个数量级(200M 与 4G)。如果我了解什么是“缓冲区”,那么我就可以开始研究为什么缓冲区在较小的系统上增长到如此大的比例。
来自man proc
(我忽略了“大”这个滑稽过时的定义):
缓冲区 %lu
原始磁盘块的相对临时存储,不应变得非常大(20MB 左右)。
缓存 %lu
从磁盘读取的文件的内存缓存(页面缓存)。不包括 SwapCached。
$ free -V
free from procps-ng 3.3.12
$ uname -r # the Linux kernel …
Run Code Online (Sandbox Code Playgroud) 有害的 USB 记忆棒停顿问题- LWN.net,2013 年 11 月。
Artem S. Tashkinov 最近遇到了一个问题,至少一些 LWN 读者会熟悉这个问题。将慢速存储设备(例如 U 盘或媒体播放器)插入 Linux 机器并向其写入大量数据。整个系统继续挂起,可能持续几分钟。
不过这一次,Artem 做了一个有趣的观察:系统在使用 64 位内核运行时会停顿,但在相同硬件上使用 32 位内核时没有遇到这样的问题。
文章解释说,对于 64 位内核,默认情况下允许脏页缓存(回写缓存)增长到内存的 20%。使用 32 位内核时,它实际上被限制在大约 180MB。
Linus 建议在 64 位上也将其限制为 ~180MB,但是当前的 Linux (v4.18) 没有这样做。将Linus 建议的补丁, 与Linux 4.18 中的当前功能进行比较。反对这种变化的最大论据来自 Dave Chinner。他指出,过多地减少缓冲会导致文件系统受到碎片化的影响。他还解释说,“对于流式 IO,我们通常需要至少 5 秒的缓存脏数据来平衡延迟。”
我很迷惑。优盘卡顿为什么会导致整个系统挂掉?
我很困惑,因为我读了一篇描述2011 年合并代码的早期文章(Linux 3.2)。它显示内核应该已经在每个设备的基础上控制脏页缓存:
无 I/O 脏节流- LWN.net, 2011
这就是Fengguang 的补丁集的用武之地。他试图创建一个控制循环,该循环能够确定在任何给定时间每个进程应该允许脏多少页。超出其限制的进程会被简单地休眠一段时间以允许写回系统赶上它们。
[...]
系统的目标是将脏页数保持在设定值;如果事情变得不合时宜,就会施加越来越大的力量,将事情带回应有的位置。
[...]
但是,如果不考虑支持设备 (BDI),则无法真正计算出该比率。一个进程可能正在弄脏存储在给定 BDI …
在 Ubuntu 18.04 系统上执行大型磁盘映像操作时,我遇到了系统范围的延迟/滞后问题。这是系统规格:
处理器:英特尔酷睿 i7(任何内核都不会接近容量)
内存:12GB(永不接近容量)
系统盘:SSD(永不接近容量)
外部磁盘:USB 3.0 5400 和 7200RPM 旋转磁盘
这些大型磁盘映像操作基本上是:
nice ionice dd if=/dev/usbdisk1 of=/dev/usbdisk2
由于我的系统文件都不在任何 USB 磁盘上,理论上,这不应该引入太多延迟。但是我发现当我对多个 USB 磁盘进行映像时,系统就会开始爬行。为什么?我的理解是每个磁盘都有自己的IO队列,那这是怎么回事呢?我该如何补救?
另外,FWIW,我根本不在乎 USB 磁盘的成像速度,因此我认为可以减慢这些操作以促进系统平稳运行的解决方案。
我一直在测试 Linux 4.18.16-200.fc28.x86_64
。根据free -h
.
我有vm.dirty*
sysctl 的默认值。 dirty_background_ratio
是 10,现在dirty_ratio
是 20。根据我读过的所有内容,我希望 Linux 在达到 RAM 的 10% 时开始写出脏缓存:0.77G。当脏缓存达到 RAM 的 20%:1.54G 时,缓冲的 write() 调用应该阻塞。
我跑过去dd if=/dev/zero of=~/test bs=1M count=2000
看着dirty
田野atop
。当dd
命令运行时,该dirty
值稳定在 0.5G 左右。这明显低于脏背景阈值(0.77G)!怎么会这样?我错过了什么?
dirty_expire_centisecs
是 3000,所以我认为这不是原因。我什至尝试降低dirty_expire_centisecs
到 100 和dirty_writeback_centisecs
10,看看这是否是限制dirty
。这并没有改变结果。
作为调查的一部分,我最初写下了这些观察结果:为什么在 2013 年报告了“USB 记忆棒停顿”问题?为什么现有的“No-I/O 脏节流”代码没有解决这个问题?
我知道在两个阈值之间的中间 - 15% = 1.155G - write() 调用开始在曲线上受到限制(延迟)。但是在这个天花板之下时不会增加延迟;允许生成脏页的进程“自由运行”。
据我了解,节流旨在将脏缓存保持在 15% 或以上,并防止达到 20% 的硬限制。它并不为每种情况提供保证。但我正在用一个dd
命令测试一个简单的案例;我认为它应该简单地限制 write() 调用以匹配设备实现的写出速度。 …