在使用linux服务器期间,由于linux使用内存原理来尽可能多地缓存,因此pagecache会占用大量内存。
suse的版本具有pagecachelimit函数,在centos中看不到。即使将此功能集成到centos中,您也会发现该设置无效。
cat /proc/sys/vm/pagecache_limit_mb0
1.将0更改为相应的值,例如12000,限制为120G,让我们看看为什么相应内核中的算法无法生效,
总页面缓存> 8 * free_pages + pagecache_limit_mb
该算法的关键是确定页面缓存限制是否触发恢复。当页面缓存设置为某个值时,系统不会直接使用该值作为判断标志,而是会添加自由限制。
从这个意义上讲,因为设置的pagecache_limit_mb相对较小,但是当有很多空闲空间时,触发此条件会更加困难。那么,增加回收利用的其他方法是什么?下面介绍了读写的两个方面。
2.是通过修改两个参数/ proc / sys / vm / dirty_background_ration和/ proc / sys / vm / dirty_ratio的大小来实现回收的。
此方案适用于大量写入:vm.dirty_background_ratio:此参数指定文件系统缓存中的脏页数何时达到系统内存的百分比(例如5%),pdflush / flush / kdmflush将被触发等待后台写回进程运行,并异步将某些缓存的脏页刷新到设备;
vm.dirty_ratio:并且此参数指定文件系统缓存的脏页数达到系统内存百分比(例如10%)时,系统必须开始处理脏页(因为脏页数为了避免数据丢失,已经经常将某些脏页刷新到外部存储器中);在此过程中,由于系统转移到处理文件IO,因此可能会阻止许多应用程序进程。
为什么我们需要两个比率?我始终错误地认为无法达到dirty_ratio的触发条件,因为每次都肯定会达到vm.dirty_background_ratio的条件。后来,根据商业现象,发现情况并非如此。的确,首先达到了vm.dirty_background_ratio的条件,然后触发了刷新过程以执行异步回写操作,但是应用程序进程仍可以在此过程中执行写操作。如果多个应用程序进程写入的数量大于刷新进程刷新的数量,则很自然可以达到由参数vm.dirty_ratio设置的阈值。此时,操作系统将切换到同步处理脏页的过程,这可能会阻止应用程序进程。
3.使用流媒体时,写入的脏页很少,大多数是读取方案,主要是sendfile或read导致许多文件进入缓存,但是访问这些文件的可能性非常低,因此,它等效于一次性使用,并且不会长时间再次使用,因此我们对页面缓存限制有强烈的要求。由于内核本身具有根据水线动态回收页面缓存的功能,因此问题的根源也可能是默认情况下最小水线和低水线之间的间隔太近,从而导致空闲内存较低时与低水位线相比,启动的kswapd恢复速度太慢,无法跟上临时大内存应用程序的节奏,因此可用内存会迅速突破最小水印,从而在内存应用程序过程中导致缓存恢复或应用程序故障,从而导致性能问题
因此,解决该问题的方法之一可以通过增加最小水位线和低水位线之间的间隔来实现
内核只是提供了这样的参数,即/ proc / sys / vm / extra_free_kbytes。设置此参数后,最小和最低水线之间的间隔将增加,以确保有足够的可用内存来应对临时的大量内存动态应用程序。
4.增加水位线和提高水位线可以帮助提前触发恢复,这等同于以后的内存需求,这可以及时触发恢复,但是当您的内存消耗速度大于内存恢复速度,仍然会有很多cahce,kswap很高。
5.如果仍然不及时回收,那么您需要降低kswap的精确级别,这将有一些帮助。将renice设置为-20。尽管在调度方面它仍低于实时过程,但仍高于调整前的水平。更高一点。
6.使用posix_madvise,madvise,fadvise并使用POSIX_MADV_DONTNEED功能,但是您不能调用太多,这很容易导致sys升高。测试时,您可以在访问几个M以找到最佳设定点后进行清理。
7.修改系统调用并输入要输入的功能值,以便系统知道它将不会放置在高速缓存中。与directio的区别在于,尝试不复制到用户模式,并区分应用方案,因为directio当前不支持调用sendfile,因此还需要一个副本,这意味着尽管搜索过程保存了address_space中的基数树后,还有从内核到用户模式的另一个内存副本。当然,我已经尝试更改Directio以支持sendfile,因为sendfile基于拼接的调用,并且在原始的Directio进程中,用户页面用作写入地址,因此有必要在Directio中检查页面自定义修改,主要是修改pmd的映射。
8.如果它是内存存储介质,即可以按字节寻址的存储介质,则可以打开DAX功能,并且在安装它时,请启用此功能,该功能绕过页面缓存。
9.这是对6的改进,具有一定的特殊性。在添加基数树之前,会主动调用invalidate_mapping_pages。这比在用户模式下释放要麻烦得多,但效果更好。
如果您有更好的方法,我希望提醒我。
此外,这个问题经常被问到缓存中保留了哪些内容。
这里要提到两种工具,一种是vmtouch,另一种是hcache。我不会发布源代码。如果您有兴趣,可以下载。
lsof | grep REG | grep mnt | sort -u | awk'{print $ 9}'| xargs vmtouch
在我们的应用程序场景中,这将累积缓存所占用的文件。如果要使用它,则需要根据文件名对其进行过滤。前提是该文件的句柄仍由pid保留,并且某些文件fd已关闭,但仍存储在系统中,因此无法获取此方法。
除了这两个查看工具外,还需要计算平板的占用量,
SlabInfo=`cat /proc/slabinfo |awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}'`
还有另一个常见问题,即访问热文件。当时,我的处理想法是每隔一段时间获取一次lsof,然后比较之前和之后的两个文件。
#!/bin/bashsum=0;whileread linedo
if [ $(grep $line $2|wc -l) -eq 1]then
echo $line >>$1_2_$2.txtsum=$(($sum+1))fi
done < $1
echo "sum=$sum"
总和数与之前和之后的文件数相同。这不是很准确,因为可以打开和关闭文件,但是如果您多次采样,效果还可以。
某些应用程序场景将尝试避免诸如视频点播之类的页面缓存,但是您不能使用dio读取,因为dio读取具有对齐要求,因此无法提前读取。常见的方法是在用户模式下使用dropcache,但是该dropcache不会相互区分,
因此,我们对内核模式进行了转换,以删除某些特定的格式,特定的大小和特定的访问时间,效果更好。
本文来自电脑杂谈,转载请注明本文网址:
https://i-blog.csdnimg.cn/blog_migrate/b79fd7f08bae6a61580a2e6b886f7647.png