page cache和buffer cache的关系

本篇作为kernel对内存的管理、page cache和buffer cache总结,会尽力描述出文件cache的一幅清晰画面。片尾还会有所讨论mmap与buffer cache。


介绍

  我们知道,硬盘的扇区大小为512bytes(至于为什么要这么设计,请参考Data alignment漫谈的背景介绍),而文件系统比如说ext4默认是以4k对齐,也就是说文件系统的一个inode对应了disk的8个sectors,与此同时linux大部分的虚拟内存页和物理内存帧也都是4k大小。
  Page cache缓存文件的页以优化文件IO。Buffer cache缓存块设备的块以优化块设备IO。
  在linux kernel 2.4之前,这两个cache是不同的:file在page cache中,disk block在buffer cache中。考虑到大多数的文件是由disk上的文件系统表示的,数据会在系统中有两份缓存,一份在page cache中,一份在buffer cache中。许多类unix系统都是这种模式。
  这种实现是很简单,但是明显的低效和冗余。在linux kernel 2.4之后,这两种caches统一了。虚拟内存子系统通过page cache驱动IO。如果数据同时在page cache和buffer cache中,buffer cache会简单的指向page cache,数据只会在内存中保有一份。Page cache就是你所知道的disk在内存中的缓存:它会加快文件访问速度。
  无论如何内核要对块设备执行基于块的IO而不是虚拟内存page。由于绝大部分的块表示文件的数据部,所以大部分的buffer cache都可由page cache表达,但是有少量的比如文件元数据仍然是保留在buffer cache中来缓存。
  我们简单看一下大概的结构。
  page cache和buffer cache的关系_第1张图片
  我们再看一下经典的linux IO图。
  page cache和buffer cache的关系_第2张图片
  嗯,是的,这个图有点乱,那我们再抽象一下看看。
  page cache和buffer cache的关系_第3张图片
  上如的控制流就是带着元数据的流转,driver中会管理着buffer cache,文件的元数据信息;而数据部直接按照数据流从page cache刷入disk的cache(磁盘也是有自己的cache的)。
  至此,page cache和buffer cache在你的脑海中有了一个清晰地印象。

By the way

  之前有看到有人说mmap不会利用buffer cache,小生特意测试了一下,从top或free命令观察的结果来看,貌似是扯淡。因为我在通echo 3 > /proc/sys/vm/drop_caches清理掉cache并等待稳定后,通过比对read/write和mmap文件操作的结果来看,buffer cache的变化基本相同,都有小幅增加。我想是不是有人看到buffer cache增加的比较小,误会了?要知道kernel 2.4之后buffer cache存储的可仅仅是元数据啊,那才多点。除非你疯狂测试小文件才能看到buffer cache的大幅增长。但是我相信mmap完全没有理由绕过buffer cache对元数据的缓存,如果那样,内核实现的也太low了,有病么?

优化

  看完上面的介绍,那么问题来了,我们需要注意什么呢?我们又能做些什么来优化性能呢?我会写一个小文件存储的简单的解决方案来说这些问题。

你可能感兴趣的:(io)