openstack-notes

上图是 Linux 写文件的一个流程图,图中主要包含三块,用户层、内核层、硬件层,Linux 在写文件时要经过系统调用、VFS、PageCache、文件系统、通用块管理层、IO调度层等多个流程后最终会将文件写入到磁盘中。而 blkio cgroup 作用在通用块管理层。Buffered I/O 是先写入到 PageCache 再走后面的流程将数据写入磁盘,而 Direct I/O 会绕过 PageCache 直接走后面的流程。

Linux 中应用程序对文件读写时默认是以 Buffered I/O 的形式写入的,此时并不需要经过通用块管理层,只需写入到 PageCache 即可,所以无法被限速,但 PageCache 中的数据总是要经过通用块管理层写入到磁盘的,原则上说也有影响,但是对于应用程序来说感受可能不一样,这与 PageCache 写入磁盘的机制也有关系。

在一般 I/O 的情况下,应用程序很可能很快的就写完了数据(在数据量小于缓存空间的情况下),然后去做其他事情了。这时应用程序感受不到自己被限速了,而内核在将数据从 PageCache 同步到磁盘阶段,由于 PageCache 中没有具体 cgroup 关联信息,所以所有 PageCache 的回写只能放到 cgroup 的 root 组中进行限制,而不能在其他cgroup 中进行限制,root cgroup 一般也是不做限制的。而在Direct IO的情况下,由于应用程序写的数据是不经过缓存层的,所以能直接感受到速度被限制,一定要等到整个数据按限制好的速度写完或者读完,才能返回。这就是当前 cgroup 的 blkio 限制所能起作用的环境限制。

PageCache 写入磁盘的机制:

(1)脏页太多,Page Cache 中的脏页比例达到一定阈值时回写,主要有下面两个参数来控制脏页比例:

(2)脏页存在太久,内核线程会周期性回写,脏页存在时间主要由以下几个参数控制: