出没于杭州和青岛的程序猿一枚,对内核略懂一二
分类: LINUX
2013-01-23 13:24:11
欢迎转载,版权所有,转载请保留文档的完整性
如果大家对pagecache或者本篇文章有任何见解,欢迎随时沟通。
pagecache科普
系统全局的pagecache和优化
基于文件的pagecache和优化
linux对文件的访问除了显示使用O_DIRECT标志,所有的访问都会经过pagecache。例如open一个文件,通过read系统调用读取数据的流程:
用户态发起read操作,传入要读取的文件的fd、偏移以及数据存储空间
陷入内核态vfs_read函数,generic_file_aio_read-->do_generic_file_read
do_generic_file_read的流程可以简化如下:
start:
if (pagecache中存在文件和偏移的页面) {
进行相应的预读策略,并将相应的内容读取到用户指定空间
} else {
生成通用块层读取策略,提交给通用块层,本进程进入uninterruptible状态,等待读取完成。
goto start;
}
从上面的流程可以看出,在非DIRECT方式下,磁盘文件操作都是经过pagecache的。
每个文件在内存中最多有一个pagecache镜像,也就是说对应同一个文件,所有的进程共享pagecache。后面讲到的vmtouch正式利用这个特性才得以正常工作。
如果pagecache能够合理的存储文件的话,会极大的提供进程运行的效率(内存操作效率 >> 磁盘操作效率)。
free
/proc/sys/vm/drop_caches
/proc/sys/vm/pagecache_limit_mb
通过free命令可以看到当前系统下总共有多少内存用于pagecache
linux-19:~ # free
total used free shared buffers cached
Mem: 8057748 6803284 1254464 0 430468 4896108
-/+ buffers/cache: 1476708 6581040
Swap: 8393920 8824 8385096
从命令的输出可以看到总共有4G多的内存用于pagecache。
虽然pagecache可以显著的优化对文件操作的性能,但是过多的pagecache会导致系统空闲内存减少,影响操作系统的整体性能,比如当空闲内存减少后会影响未进入pagecache的文件的读取性能。
我们可以通过命令强制内核释放掉pagecache,命令如下所示:
echo “1” > /proc/sys/vm/drop_caches
上述命令执行完后,会暂时释放掉pagecache,如果要想一直保证系统有足够的空闲内存,可以通过一个crontab来定时执行上面的命令(这可不是内核的风格^_^)。于是Vaidyananthan Srinivasan添加了一个参数pagecache_limit_mb来防止pagecache积聚导致系统性能下降的问题(从2.6.20内核开始演进过来,之前的参数包括pagecache_ratio,不过最新的内核都删除了这些参数,使用了cleancache)。
关于pagecache_limit_mb参加附录1,关于cleancache参加附录2
vmtouch
在做性能优化的时候,经常会用到查看特定的某些文件的pagecache情况,那么内核是不是提供相应的工具呢?
很遗憾,或许是因为这个工具太过简单,以至于一直没能进入内核的tools列表。关于这个工具的代码详见附录3
这个工具提供了查看指定文件的pagecache情况,以及强制对文件进行pagecache和清除pagecache。这里主要使用了两个系统调用mincore和posix_fadvise。
例如查看文件file1的pagecache情况
linux-12:~/performance/testfile # /root/vmtouch file1
Files: 1
Directories: 0
Resident Pages: 302428/302428 1G/1G 100%
Elapsed: 0.025512 seconds
从这里可以看出,文件file1一共有302428个页面,全部都在内存里面。