为什么要在Linux中删除缓存?


84

在我们的服务器中,我们习惯于在午夜删除缓存。

sync; echo 3 > /proc/sys/vm/drop_caches

当我运行代码时,似乎释放了很多RAM,但是我确实需要这样做。可用内存不是浪费吗?


62
找到把它放进去的人,问他为什么这样做。正如您正确猜测的那样,没有明显的理由。
迈克尔·汉普顿

10
调试内核。就是这样 这实际上并没有释放任何RAM。顾名思义,它会丢弃高速缓存,从而降低性能。
迈克尔·汉普顿

28
@ivcode然后,您应该找到并修复该服务器的问题,而不是避免引起该问题的情况。如果每次我向右急转弯时汽车都失速了,那么避免急转弯是一个糟糕的解决方法。
David Schwartz

7
相关thedailywtf.com/Articles/Modern-Memory-Management.aspx强烈认为这是一个坏主意。
Drunix 2014年

7
相关的“问题”的有用描述:linuxatemyram.com
Bill Weiss

Answers:


86

您是100%正确的。这是以释放RAM一个很好的做法。这可能是货物崇拜系统管理的一个示例。


9
+1代表提及“货物崇拜系统管理”。任何不知道该术语及其含义的系统管理员都应被解雇。
托尼2014年

8
@Tonny:那我们就没有系统管理部门了:(
PlasmaHH 2014年

2
像大多数人一样,我喜欢简短的断言,但得到了很多认可,但引用或推理将使我的超我获得+1。
亚伦·霍尔

2
如果您不介意的话,请解释货运管理以及上述内容。也许在后续编辑中?我仍未保留我的+1 ...:P
亚伦·霍尔

2
“可能的是,尽管您的应用程序可能没有使用这些RAM,但是Linux正在积极地将其缓存到其内存中,即使该应用程序需要内存,它也不会释放其中的某些缓存,而是开始进行交换。” 不太具体。在实践中,内存管理不是完美的,当出现缺陷时转动旋钮是一件好事。
丹·普里兹

62

是的,清除缓存将释放RAM,但是这会导致内核在磁盘上而不是在缓存中查找文件,这可能会导致性能问题。

通常,当可用RAM耗尽时,内核会清除缓存。它经常使用pdflush将脏内容写入磁盘。


20
+1解释为什么这是一个坏主意。
Ogre Psalm33

35

这样删除高速缓存的原因是为了对磁盘性能进行基准测试,这是它存在的唯一原因。

在运行I / O密集型基准测试时,您要确保尝试的各种设置实际上都是在执行磁盘I / O,因此Linux允许您删除缓存而不是完全重新引导。

引用文档

该文件不是控制各种内核高速缓存(inodes,dentries,页面高速缓存等)增长的一种手段,当系统上其他地方需要内存时,内核会自动回收这些对象。

使用此文件可能会导致性能问题。由于它丢弃了缓存的对象,因此重新创建被丢弃的对象可能会花费大量的I / O和CPU,尤其是当它们使用过多时。因此,不建议在测试或调试环境之外使用。


当然,根据您要尝试执行的操作,即使完全重新启动也可能无法充分清除磁盘缓存。
2014年

1
设计目标是“需要内存时内核自动回收这些对象”,但这可能并不总是实际的行为。
丹·普里兹

@DanPritts是什么让您认为事实并非如此?
2015年

2
很明显的情况是,当您想清除RAM以允许分配更多(非透明)大页面时;另一种情况是透明的大页面垃圾回收暂停错误(请参阅我在该问题上其他地方的回答/评论)。但是我的评论只针对一般情况。有时,操作该系统的人员比设计/实现该系统的人员了解得更多。通常,不是-这就是他们的评论试图避免的内容。我很高兴
Dan Pritts 2015年

26

这里的基本思想可能还不错(只是非常幼稚和误导):可能有正在缓存的文件,例如在不久的将来不太可能访问的文件。这些“吃掉”的内存,稍后在必要时将由操作系统以一种或另一种方式释放。

取决于交换设置,文件访问模式,内存分配模式以及更多不可预测的事情,有可能发生的情况是,当您不释放这些缓存时,它们稍后将被强制重用,这需要花费更多的时间。从未使用的内存池中分配内存。在最坏的情况下,Linux的swappiness设置将导致程序存储器被换出,因为linux认为这些文件在不久的将来比程序存储器更可能被使用。

在我的环境中,Linux经常会猜错,并且在大多数欧洲证券交易所开始时(当地时间0900左右),服务器将开始执行它们每天仅执行一次的操作,需要交换以前由于写入而换出的内存日志文件,压缩它们,将它们复制等正在将缓存填满,以至于必须将其交换出去。

但是,删除缓存是否可以解决此问题?绝对不是。这里的解决方案是告诉linux不知道的东西:这些文件可能不再使用了。这可以通过编写应用程序使用posix_fadvise()或使用cmd线工具vmtouch(也可以用于查看事物以及缓存文件)来完成。

这样,您可以从缓存中删除不再需要的数据,并保留应缓存的内容,因为删除所有缓存时,必须从磁盘重新读取很多内容。那是在最坏的时刻:何时需要;在您的应用程序中造成明显的延迟,并且通常是不可接受的。

您应该拥有的是一个系统,该系统可以监视您的内存使用模式(例如,某些事物正在交换),然后进行相应的分析并采取相应的措施。解决方案可能是在一天结束时使用vtouch逐出一些大文件。也可能是增加更多的内存,因为服务器的每日高峰使用量就是这样。


我服务器上的所有应用程序都在nohup上运行。也许nohup.out正在被缓存并耗尽了内存?
ivcode 2014年

@ivcode:这可能是一个原因,请检查nohup.out的大小。也许使用vmtouch可以计算出缓存了多少。
PlasmaHH 2014年

cat /dev/null > path/nohup.out随着nohup.out的迅速发展,我每隔15分钟就要完成一次正式任务。也许linux正在缓存nohup.out,即使我正在清除它
ivcode 2014年

5
@ivcode如果不需要输出,nohup则应将其重定向到/dev/null。听起来您有时在系统上有一些经验不足的系统管理员。参见stackoverflow.com/questions/10408816/…,了解如何将nohup输出引导至/dev/null
David Wilkins,2014年

尽管每隔15分钟会清除一次nohup.out,但如果由于某种原因而终止了应用程序进程,则nohup.out将自动从另一个脚本进行备份。我尝试了vmtouch。这确实是一个非常好的工具
ivcode 2014年

16

我看到启动一堆虚拟机时,丢弃缓存非常有用。或其他使用大页面的东西,例如某些数据库服务器。

Linux中的大页面通常需要对RAM进行碎片整理,以便找到2MB的连续物理RAM放入页面中。释放所有文件缓存使此过程非常容易。

但是我同意大多数其他答案,因为通常没有理由每天晚上删除文件缓存。


1
我赞成指出二阶偏见是对丢弃缓存的响应。
Noah Spurrier 2014年

1
同样,在高内存节点(1Tb)上的HPC应用程序中,读入一些大文件会导致缓存大量内存。由于许多HPC应用程序执行数百GB的malloc,因此系统可能会停滞数小时,因为一旦系统到达缓存的内存“边界”,迁移过程便会在NUMA节点之间毫无意义地移动碎片化内存的微小块。更糟糕的是,除了诱使系统立即分配所有它可以立即释放的所有2MB细小块之外,您无法在用户空间中释放缓存,这无济于事,这使大页碎片整理和应用程序能够正常运行。
user1649948 '17

+1创建大页面的命令(sysctl -w vm.nr_hugepages=...)甚至无法工作,除非我先删除高速缓存(Arch linux)。
Aleksandr Dubinsky

8

当没有人真正拥有发现问题的技能或经验时,这可能是一种稳定系统的方法。

释放资源

删除高速缓存本质上将释放一些资源,但这具有使系统实际上更难以执行其要执行的操作的副作用。如果系统交换(试图读取并从磁盘交换分区写入速度比它实际上是能够)再滴加缓存定期可以缓解症状,但无助于根治的原因

什么是吞噬记忆?

您应该确定是什么导致大量内存消耗,从而导致删除高速缓存似乎可以正常工作。这可能是由于任何数量的配置不当或只是简单地错误使用服务器进程引起的。例如,在一台服务器上,当Magento网站在15分钟的间隔内达到一定数量的访问者时,我见证了内存利用率最大化。这最终是由于将Apache配置为允许太多进程同时运行而引起的。进程太多,占用大量内存(Magento有时是野兽)=交换。

底线

不要仅仅认为这是必要的。主动找出原因所在,如果其他人认为它是错误的,则有胆量禁用它,并观察系统-了解真正的问题并解决。


4

Linux / m68k实际上有一个内核错误,该错误会导致kswapd疯狂并吞噬100%的CPU(如果还有其他CPU绑定任务,例如Debian二进制软件包autobuilder – vulgo –已经运行),则将消耗50%的CPU。时间;并非总是如此)可通过每隔几个小时运行一次此特定命令来缓解。

话虽这么说……您的服务器很可能不是m68k(Atari,Amiga,Classic Macintosh,VME,Q40 / Q60,Sun3)系统;-)

在这种情况下,插队的人要么遵循一些可疑的建议,要么充其量是过时的建议,或者对如何使用RAM产生了错误的想法(现代思维确实表示“空闲RAM浪费了RAM”并建议进行缓存) ,或“发现”此问题“解决”了其他问题(并且懒得寻找适当的解决方法)。


“导致kswapd疯狂的内核错误”-这是哪个错误?

@Ben看到了这个线程(此消息和一些后续操作,其中包括猜测可能来自何处)
mirabilos 2015年

1
我遇到了类似的问题(尽管它是x86_64的),而这时唯一的解决办法是放弃缓存serverfault.com/questions/740790/...
阿隆索

2
@Fernando我对m68k的框“滴缓存”的cronjob以及☹
mirabilos

3

一个原因可能是该站点正在运行某种监视,该监视检查免费RAM的数量,并在免费RAM下降到一定百分比以下时向管理员发送警告。如果该监视工具足够愚蠢,无法在自由内存计算中不包括缓存,则它可能会发送错误警告;定期清空缓存可以抑制这些警告,同时仍然允许工具在“实际”内存变低时发出通知。

当然,在这种情况下,真正的解决方案是修改监视工具,以将缓存包括在自由内存计算中。清理缓存只是一种解决方法,也是一种不好的选择,因为当进程访问磁盘时,缓存将快速重新填充。

因此,即使我的假设是正确的,缓存清理也不是很有意义的事情,但是对于那些没有能力解决主要问题的人来说,这只是一种解决方法。


3

我可以想到一个合理的理由,在每晚的Cron工作中执行此操作。

在大型系统上,定期删除缓存可能很有用,这样您就可以消除内存碎片。

内核透明大页面支持会定期进行内存扫描,以将小页面合并为大页面。在退化的情况下,这可能会导致系统暂停一到两分钟(我的经验是在RHEL6中;希望它有所改善)。删除缓存可能会使大型页面清除程序有一些工作空间。

您可能会争辩说,这是禁用透明大页面的一个很好的理由。OTOH您可能会相信透明大页带来的整体性能提高值得拥有,并且值得付出每天丢失一次缓存的代价。


我想过了另一个原因,尽管您不是在做正式的工作,但您仍想这样做。在虚拟化系统将VM迁移到新硬件之前,这将是一个很好的时机。较少的内存内容可复制到新主机。当然,您最终将不得不从存储中读取内容,但是我可能会权衡取舍。

我不知道任何virt软件是否确实可以做到这一点。


1
您有任何资料来源吗?如果这是一个问题,这听起来应该在内核中进行修复。
gparent 2015年

3
我对透明大页面的停顿有个人经验。RHEL6,Dell R810、4CPU,64GB RAM。禁用透明的大页面(有一个/ proc文件可以这样做)立即修复了暂停。当时我没有尝试过缓存删除技术。相反,我将Java应用程序重新配置为使用非透明的大页面,并禁用了透明的大页面。IIRC,我们对情况进行了充分调查,以认识到我们并不是唯一受影响的人,并且Red Hat知道了这个问题。
Dan Pritts 2015年

您好Dan,我在服务器上进行了相同的设置。我使用大量数据进行工作,并且在同一个python程序进行10次以上的计算后(第一次计算时间的2-3倍),性能急剧下降。如果看一看,内存缓存大小非常大,超过100 GB。而且,如果刷新此内存缓存并重新运行程序,我将获得最初的计算时间。您是否有任何文件或信息可以分享这种现象?谢谢。
Axel Borja

1
access.redhat.com/solutions/46111对其进行了描述。您可以禁用透明的大页面,以查看是否是您的问题。
Dan Pritts

2

我想补充我的两分钱:系统了解很清楚,这些内存页面缓存,当一个应用程序要求的内存需要将下降很多。

一个相关的设置是/proc/sys/vm/swappiness,它告诉内核在进行新的内存分配时更喜欢删除内存缓存或交换“空闲”分配的内存页。


1

问题是从2014年开始的,但是由于这一问题在某些隐藏的centos 6.8后端上一直存在,因此对于某些人可能仍然有用。

https://github.com/zfsonlinux/zfs/issues/1548 描述了zfs的问题。在那里,无法为已删除的文件释放磁盘空间,因为如果在zfs上使用nfs,则不会从内核的inode缓存中删除文件的inode。

引用错误线程的话,behlendorf,2015年1月6日写道:

当前的推测是由于某种原因,NFS服务器保留了文件句柄的缓存版本。在NFS服务器删除该文件句柄之前,ZFS无法取消链接此文件。一些简单的测试表明,在服务器上删除高速缓存将导致该引用被删除(例如NFS文件句柄),此时将正确释放空间。内存压力也可能导致内存下降。

例如,如果您不希望因停机而重组zfs,则夜间echo 3> / proc / sys / vm / drop_caches是解决该错误的最简单方法。

因此,也许不是货物崇拜管理,但原因是一些相当好的调试。


0

这在NUMA(非统一内存访问)系统上可能是有意义的,在该系统上,通常每个CPU(套接字)都可以透明地访问所有内存,但是与并行HPC应用程序关联,可以比其他套接字的内存更快地访问其自己的内存。

许多简单的并行应用程序倾向于从单个进程执行文件I / O,从而在退出时在分配给磁盘高速缓存的单个NUMA节点上留下很大一部分内存,而在另一个NUMA节点上,内存可能大部分都是空闲的。在这种情况下,据我所知,由于Linux内核中的缓存回收过程仍不支持NUMA,因此在已将内存分配给缓存的NUMA节点上运行的进程被迫在另一个NUMA节点上分配内存,只要另一个节点上有可用的RAM,就会破坏性能。

但是,在HPC系统中,明智的做法是在开始新的用户作业之前而不是在cron的特定时间清理缓存。

对于非并行应用程序,此问题不太可能出现。


0

当页面缓存很大(比当前的交换使用量大很多),并且交换和交换又交替发生时,这就是您需要删除缓存的时候。我已经看到在运行Ubuntu 16.04LTS的我的MariaDB数据库服务器之一中内存使用率增加的情况,而Linux只是选择增加交换使用率,而不是删除未使用的页面缓存。我的系统中已经禁用了透明的大页面,因为TokuDB要求将其禁用。无论如何,也许这不是一个错误,但是linux仍然在做这种行为令我感到困惑。各种资料表明,Linux将在应用程序请求时删除页面缓存:

但是现实并非如此简单。解决方法是:

  1. 定期执行放置缓存
  2. 必要时执行放置高速缓存(使用vmstat 1进行活动交换的监视器)
  3. 建议linux使用dd或python-fadvise等实用工具从缓存中删除某些文件(例如apache日志文件)。参见https://unix.stackexchange.com/questions/36907/drop-a-specific-file-from-the-linux-filesystem-cache

例子dd run:

dd if=/var/log/apache2/access_log.1 iflag=nocache count=0

示例python-fadvise:

pyadvise -d /var/log/apache2/access_log.1


-5

我有一台在PAE内核上运行16GB RAM的台式机。一两个小时后,磁盘性能会急剧下降,直到删除高速缓存为止,因此我将其放入cron。我不知道这是否是PAE内核的问题,或者如果有足够的内存,那么缓存的实现是如此缓慢。


9
这是“货物崇拜”系统管理的一个典型示例:您无需掩盖并解决问题,而只是掩盖它。
迈克尔·汉普顿

2
有时权宜之计是正确的解决方案。它可能只是推迟解决实际问题,或者可能是这种情况下所需的解决方案。即使这是一种不好的做法,也仍然不是“崇拜货物”。有一个已证明的因果关系:丢弃缓存和磁盘性能得到改善。
Dan Pritts 2015年

1
CCSA最初定义的一部分是将因果关系误认为是因果关系,现在就到了。通过解决相关但非因果的实体来掩盖问题是解决问题的最佳方法,这是CCSA的概念正试图警告的问题。
underscore_d
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.