您的位置:首页 > 运维架构 > Linux

linux_2.6内核内存缓冲与I/O调度机制:到底是BIO还是BH?答案是BIO与BH

2011-12-01 11:25 701 查看
kaiwii出品,欢迎斧正!

背景知识

块设备与字符串设备

块设备与字符串设备的最大区别是,块设备里面的数据支持随机读取,而字符串设备必须要按照顺序连续读取。

以字符串设备-键盘为例。输入字符串-”Kaiwii”。在读取设备中的内容的时候,如果不按照顺序,读取为“iiwiaK”,这个数据就没意义了。同样的,如果不连续读取数据,比如先读“Kai”,读取出来的内容就与真实的数据大相径庭。

但是,如果使用块设备就不一样了。每个块都是独立自主的。先读块A后读块B,与先读块B后读块A没有半点不同。

扇区、页、块的关系

首先按照具体物理位置进行划分,扇区属于硬盘的范畴,页属于内存的范畴。而块是一个沟通硬盘设备与内存的逻辑概念。

其中,块的大小没有统一的要求,视具体的块设备而定。但是,有一点可以确定的是:在硬盘上,一个块通常包括整数倍个扇区;而在内存上,一个块的大小肯定并且远远少于一个页的大小。

下面,从块的理解出发谈谈他们三者之间的关系。首先,要搞清楚为什么要有块这个概念。文件管理系统管理的最小粒度是文件。而一个文件是由若干个块组成的。而所谓的读取一个文件,指的是将硬盘中的内容读取到内存中去,而这个过程中操作的最小粒度是块。在硬盘中,以块为单位(即若干个扇区为一组)组成一个链来储存一个文件。在读取过程中,在硬盘中的一个文件的各个块将会一个接着一个读取到内存的某个页的某个缓冲区上。说到这里,一切都豁然开朗了吧。

正言

BH

全称:buffer_head

API介绍:

Historically, a buffer_head was used to map a single block within a page, and of course as the unit of I/O through thefilesystem and block layers.

Nowadays the basic I/O unit is the bio, and buffer_heads are used for extracting block mappings (via a get_block_t call), for tracking state within a page (via a page_mapping) and for wrappingbio submission

for backward compatibility reasons(e.g.submit_bh).

译文:

在过去的版本中,buffer_head不但用来映射页面里面的一个块,而且作为文件系统与块设备进行I/O交互的最小单位。

在现在的2.6版本中,最小的I/O单元是bio。然而为了可以通过get_block_t 调用来提出文件块里面的信息(主要是指:缓冲区与块设备里面储存的文件块之间的映射关系),可以通过page_mapping方法跟踪页面里面的各个缓冲区的状态(主要是指:某个缓冲区映射到块设备的哪个文件块上),可以通过例如submit_bh等方法来包装一个bio请求来实现对旧有版本的支持,buffer_head在现有的2.6版本中仍然得到保留。

BIO

全称:block I/O model

API介绍:

main unit of I/O for the block layer and lower layers (ie drivers and stacking drivers)

译文:

与块设备和底层设备(例如驱动和堆栈驱动)进行I/O交互的主要单位。

BH与BIO的关系

撇开BIO与BH在历史上的传承关系。就以现有的2.6版本关系,谈谈他们两者的联系。

我们可以这么理解,BH是为方便文件管理的组织为生的。随着linux版本的推演,很多东西都在变化,但是对于文件管理有一点不变的是,文件仍然是用文件块链的方式来储存的。BH对应内存中的一个缓冲区,而一个缓冲区又对应一个文件块,而且BH还记录了这个硬盘中的文件块与内存中的缓冲区的映射关系。试想一下,如果在linux的系统中没有这种机制来记录这个映射关系,我们怎么读入一个文件,即使读入了一个文件的某个块,那么又怎么找到剩下的块呢……感觉没有了这种映射关系,一切都乱套了。

而BIO,正如其名,是为了I/O操作而生的。在BIO没有出现之前,I/O操作是一个页面接着一个页面地进行的。试想一下这样子的一个情景。一个文件由A、B、C三个文件块组成。其中,A、B都是直接存储这个文件的信息的而且都同时在甲柱面的,C也是。但有一点很不幸运的是,C块是一个间接寻址,它指向的另外一个柱面-柱面乙的。如果按照旧路子,那么就在磁盘操作中,磁盘针就需要先将A、B读取进内存,然后跑老远的路去读取C指向的其他柱面的文件块。很容易发现,这样子做是很低效的。但是,如果我们先去读取A、B,然后在需要读取柱面乙的其他内容的时候,再一并读取C所指示的块会显得更加高效。之所以设置BIO这样子一个概念就是为了实现这个目的。回到我们的例子,读取A、B可以作为一个BIO,读取C指示的内容与乙柱面指示的内容可以作为另外一个BIO。当然,如何划分一个BIO,可以有其他的标准。但是,从这个例子出发,我们至少明白一点的是,有了BIO,我们在调度I/O的时候,可以通过实现某些算法来引入其他高效的调度方式。但是,需要注意的是,这些涉及到BIO的调度,是代码层面的。

说了这么多,Kaiwii打算用一个生活中的例子来串起BIO与BH的关系。不知道大家有没有做过销售?小弟不才,在读本科的时候,曾经兼职过销售。一般的大公司,关于某一个地点,比如说广州市海珠区江南西路,都会有一个详细的客户名单,记录了某个客户的联系方式,名字,地点等重要信息的。而BH就如同这个客户名单,记录着该缓冲区映射的文件块详细地址和相关信息。销售的第一课莫过于拜访客户。作为一个销售人员,每天的工作莫过于根据拜访计划去拜访客户。所以,每天晚上,销售人员都会根据客户的具体情况,比如说,地点之间的远近,是否有空等,指定新的一天的拜访计划。而BIO就好比一个拜访计划。当然,要做好一个好的拜访计划就需要一个好的策略,这个策略就好比一个好的系统总会使用好的算法来实现一个合理调度方式。

总结

到底是BIO还是BH?答案是BIO与BH。

Bh是文件组织的最小单元

Bio是文件I/O读取的最小单元

kaiwii出品,欢迎斧正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: