Page Cache的落地问题
除非特别说明,否则本文提到的写操作都是 buffer write/write back。
起因
前几天讨论到一个问题:Linux 下文件 close成功,会不会触发 “刷盘”?
其实这个问题根本不用讨论,查一下就知道。
man 2 close
的 NOTES
一节里有这么一段话:
A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a filesystem to flush the buffers when the stream is closed. If you need to be sure that the data is physically stored use fsync(2). (It will depend on the disk hardware at this point.)
所以,一个文件的描述符被 close 成功,并不会触发操作系统刷盘。
那么,问题来了,除了主动调用fsync
(或相关函数)之外,Linux 什么时候会“刷盘”呢?
一次正常的写流程
一次写数据的典型流程(不考虑异常和其它特殊情况):
1、数据在用户态的 buffer 中,调用 write 将数据传给内核;
2、数据在 Page Cache 中,返回写入的字节数(成功返回);
3、内核将数据刷新到磁盘。
第二步如果返回成功,说明数据已经到达操作系统的Page Cache,可以保证的是如果进程挂了,但是操作系统没挂,数据不会丢失。
如果调用 fsync
将数据刷新到磁盘上,返回成功,说明数据已经刷新到硬件上了——我们一般认为如果 fsync
返回成功,则表示数据持久化成功。
Page Cache 的异步刷新
那么,如果不调用fsync或其它类似功能的接口,Page Cache 是什么时候刷回磁盘的呢?
简单总结一下,有两种情况:
1、脏页太多。
2、脏页太久。
这些都由 Linux 内核的后台线程执行。相关的控制参数有:
说明: centy 中文意思是“百分之十”。
$ sysctl -a | grep dirty
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 5
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 10
vm.dirty_writeback_centisecs = 500
- dirty_writeback_centisecs 表示多久唤醒一次刷新脏页的后台线程。这里的500表示5秒唤醒一次。
- dirty_expire_centisecs 表示脏数据多久会被刷新到磁盘上。这里的3000表示 30秒。
- dirty_background_ratio 表示当脏页占总内存的的百分比超过这个值时,后台线程开始刷新脏页。这个值如果设置得太小,可能不能很好地利用内存加速文件操作。如果设置得太大,则会周期性地出现一个写 IO 的峰值。
- dirty_ratio 当脏页占用的内存百分比超过此值时,内核会阻塞掉写操作,并开始刷新脏页。
- dirty_background_bytes、dirty_bytes 是和 dirty_background_ratio、dirty_ratio 表示同样意义的不同单位的表示。两者不会同时生效。
总结
触发刷新脏页的条件:
1、调用fsync等。
2、脏页太多(相关参数:dirty_background_ratio与dirty_ratio)。
3、脏页太久(相关参数:dirty_expire_centisecs)。
参考资料
作者:linjinhe
链接:https://www.jianshu.com/p/ed5900d31f1f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Page Cache的落地问题的更多相关文章
- Page cache和Buffer cache[转1]
http://www.cnblogs.com/mydomain/archive/2013/02/24/2924707.html Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的 ...
- page cache 与 page buffer 转
page cache 与 page buffer 标签: cachebuffer磁盘treelinux脚本 2012-05-07 20:47 2905人阅读 评论(0) 收藏 举报 分类: 内核编程 ...
- 【转】Linux Page Cache的工作原理
1 .前言 自从诞生以来,Linux 就被不断完善和普及,目前它已经成为主流通用操作系统之一,使用得非常广泛,它与Windows.UNIX 一起占据了操作系统领域几乎所有的市场份额.特别是在高性能计算 ...
- linux page cache和buffer cache
主要区别是,buffer cache缓存元信息,page cache缓存文件数据 buffer 与 cache 是作为磁盘文件缓存(磁盘高速缓存disk cache)来使用,主要目的提高文件系统系性能 ...
- Page Cache buffer Cache
https://www.thomas-krenn.com/en/wiki/Linux_Page_Cache_Basics References Jump up ↑ The Buffer Cache ( ...
- 工作于内存和文件之间的页缓存, Page Cache, the Affair Between Memory and Files
原文作者:Gustavo Duarte 原文地址:http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait ...
- page cache和buffer cache
因为要优化I/O性能,所以要理解一下这两个概念,这两个cache着实让我迷糊了好久,通过查资料大概明白了两者的区别,试着说下. page cache:文件系统层级的缓存,从磁盘里读取的内容是存储到这里 ...
- Page Cache, the Affair Between Memory and Files
Previously we looked at how the kernel manages virtual memory for a user process, but files and I/O ...
- page cache 与free
我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下: 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了物理内存的总量(tota ...
随机推荐
- A: Absolutely Simple---巴什博弈
A: Absolutely Simple 时间限制: 1 s 内存限制: 128 MB 题目描述 Ocean暑假去海边玩,海边有许多好看的贝壳.并且Ocean捡了好多回来. 回 ...
- docker 容器 centos + tomcat + jdk
环境: 阿里云ecs服务器 步骤: 1.安装docker 2.获取centos镜像 3.下载tomcat 和 jdk 安装包 4.配置 1.安装docker https://www.cnblogs.c ...
- 解决GitHub下载很慢的问题
此方法参照 github下载慢,轻松提速教程 1.获取github的IP地址.访问:https://www.ipaddress.com/ 网址依次获取以下三个网址的IP github.com gith ...
- 描边shader(法线外拓)
描边的思路是需要两个pass.第一个pass让顶点沿着法线方向延伸出去,使得模型变大一圈.第二个pass正常渲染,让正常渲染的模型挡在第一个pass之上,这样就会露出延伸出去的部分,延伸出去的就是我们 ...
- fix the issue that disk space is not the size that aws ec2 have.
在申请aws ec2时,按照向导,在选择存储的时候默认硬盘大小是 8 G,这时候可以根据自己的需要输入一个合适的数字,例如100.完成向导并启动ec2 instance 后登陆机器.使用命令: df ...
- c++ 网络编程(八) LINUX-epoll/windows-IOCP下 socket opoll函数用法 优于select方法的epoll 以及windows下IOCP 解决多进程服务端创建进程资源浪费问题
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9622548.html 锲子:关于并发服务器中的I/O复用实现方式,前面在网络编程系列四还是五来 ...
- 【随笔】 MyEclipse2014的安装和破解
MyEclipse,是在eclipse 基础上加上了自己的插件.MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java.Java EE以及 ...
- Android Studio修改程序包名
我也是在网上看到的,并且这个方法只能这么修改:cn.example.xxx修改为cn.example.yyy ,修改到根目录下... refactor---rename修改 然后clean,buil ...
- 跨域拦截Access-Control-Allow-Origin设置多个origin
在Extjs和java项目碰到了需要同时处理跨域,外部要访问后台接口的问题 原来的代码是这样,只能设置一个extjs前台需要过滤的跨域请求 package com.xgt.config; import ...
- Table Code
post.PostToTags.Where(t => tagArray.Contains(t.PostTag.Name, comparerWihtoutCases) && !t. ...