说说IO(四)- 文件系统

文件系统各有不同,其最主要的目标就是解决磁盘空间的管理问题,同时提供高效性、安全性。如果在分布式环境下,则有相应的分布式文件系统。 Linux 上有 ext 系列, Windows 上有 Fat 和 NTFS 。如图为一个 linux 下文件系统的结构。

 

其中 VFS ( Virtual File System )是 Linux Kernel 文件系统的一个模块,简单看就是一个 Adapter ,对下屏蔽了下层不同文件系统之间的差异,对上为操作系统提供了统一的接口 .

中间部分为各个不同文件系统的实现。

再往下是 Buffer Cache 和 Driver 。


文件系统的结构

各种文件系统实现方式不同,因此性能、管理性、可靠性等也有所不同。下面为 Linux Ext2 ( Ext3 )的一个大致文件系统的结构。



Boot Block 存放了引导程序。

Super Block 存放了整个文件系统的一些全局参数,如:卷名、状态、块大小、块总数。他在文件系统被 mount 时读入内存,在 umount 时被释放。



上图描述了 Ext2 文件系统中很重要的三个数据结构和他们之间的关系。

Inode : Inode 是文件系统中最重要的一个结构。如图,他里面记录了文件相关的所有信息,也就是我们常说的 meta 信息。包括:文件类型、权限、所有者、大小、 atime 等。 Inode 里面也保存了指向实际文件内容信息的索引。其中这种索引分几类:

 

  • 直接索引:直接指向实际内容信息,公有 12 个。因此如果,一个文件系统 block size 为 1k ,那么直接索引到的内容最大为 12k
  • 间接索引
  • 两级间接索引
  • 三级间接索引

 

 

如图:


Directory 代表了文件系统中的目录,包括了当前目录中的所有 Inode 信息。其中每行只有两个信息,一个是文件名,一个是其对应的 Inode 。需要注意, Directory 不是文件系统中的一个特殊结构,他实际上也是一个文件,有自己的 Inode ,而它的文件内容信息里面,包括了上面看到的那些文件名和 Inode 的对应关系。如下图:


Data Block 即存放文件的时间内容块。 Data Block 大小必须为磁盘的数据块大小的整数倍,磁盘一般为 512 字节,因此Data Block 一般为 1K 、 2K 、 4K 。

 

Buffer Cache

Buffer & Cache

虽然 Buffer 和 Cache 放在一起了,但是在实际过程中 Buffer 和 Cache 是完全不同了。 Buffer 一般对于写而言,也叫“缓冲区”,缓冲使得多个小的数据块能够合并成一个大数据块,一次性写入; Cache 一般对于读而且,也叫“缓存”,避免频繁的磁盘读取。如图为 Linux 的 free 命令,其中也是把 Buffer 和 Cache 进行区分,这两部分都算在了 free 的内存。


Buffer Cache

Buffer Cache 中的缓存,本质与所有的缓存都是一样,数据结构也是类似,下图为 VxSF 的一个 Buffer Cache 结构。


这个数据结构与 memcached 和 Oracle SGA 的 buffer 何等相似。左侧的 hash chain 完成数据块的寻址,上方的的链表记录了数据块的状态。

 

Buffer vs Direct I/O

文件系统的 Buffer 和 Cache 在某些情况下确实提高了速度,但是反之也会带来一些负面影响。一方面文件系统增加了一个中间层,另外一方面,当 Cache 使用不当、配置不好或者有些业务无法获取 cache 带来的好处时, cache 则成为了一种负担。

        适合 Cache 的业务:串行的大数据量业务,如: NFS 、 FTP 。

        不适合 Cache 的业务:随机 IO 的业务。如: Oracle ,小文件读取。

 

块设备、字符设备、裸设备

这几个东西看得很晕,找了一些资料也没有找到很准确的说明。

从硬件设备的角度来看,

 

  • 块设备就是以块(比如磁盘扇区)为单位收发数据的设备,它们支持缓冲和随机访问(不必顺序读取块,而是可以在任何时候访问任何块)等特性。块设备包括硬盘、 CD-ROM  和  RAM  盘。
  • 字符设备则没有可以进行物理寻址的媒体。字符设备包括串行端口和磁带设备,只能逐字符地读取这些设备中的数据。

 

 

从操作系统的角度看(对应操作系统的设备文件类型的 b 和 c ),

# ls -l /dev/*lv

brw-------    1 root      system        22,   2 May 15 2007   lv

crw-------    2 root      system        22,   2 May 15 2007   rlv

 

  •   块设备能支持缓冲和随机读写 。即读取和写入时,可以是任意长度的数据。最小为 1byte 。对块设备,你可以成功执行下列命令: dd if=/dev/zero of=/dev/vg01/lv bs=1  count=1 。即:在设备中写入一个字节。硬件设备是不支持这样的操作的(最小是 512 ),这个时候,操作系统首先完成一个读取(如 1K ,操作系统最小的读写单位,为硬件设备支持的数据块的整数倍),再更改这 1k 上的数据,然后写入设备。
  • 字符设备只能支持固定长度数据的读取和写入 ,这里的长度就是操作系统能支持的最小读写单位,如 1K ,所以块设备的缓冲功能,这里就没有了,需要使用者自己来完成。由于读写时不经过任何缓冲区,此时执行 dd if=/dev/zero of=/dev/vg01/lv bs=1 count=1 ,这个命令将会出错,因为这里的 bs ( block size )太小,系统无法支持。如果执行 dd if=/dev/zero of=/dev/vg01/lv bs=1024  count=1 ,则可以成功。这里的 block size 有 OS 内核参数决定。

 

如上,相比之下,字符设备在使用更为直接,而块设备更为灵活。文件系统一般建立在块设备上,而为了追求高性能,使用字符设备则是更好的选择,如 Oracle 的裸设备使用。

 

裸设备

裸设备也叫裸分区,就是没有经过格式化、没有文件系统的一块存储空间。可以写入二进制内容,但是内容的格式、其中信息的组织等问题,需要使用它的人来完成。文件系统就是建立在裸设备之上,并完成裸设备空间的管理。

 

CIO

CIO 即并行 IO ( Concurrent IO )。在文件系统中,当某个文件被多个进程同时访问时,就出现了 Inode 竞争的问题。一般地,读操作使用的共享锁,即:多个读操作可以并发进行,而写操作使用排他锁。当锁被写进程占用时,其他所有操作均阻塞。因此,当这样的情况出现时,整个应用的性能将会大大降低。如图:


CIO 就是为了解决这个问题。而且 CIO 带来的性能提高直逼裸设备。当文件系统支持 CIO 并开启 CIO 时, CIO 默认会开启文件系统的 Direct IO ,即:让 IO 操作不经过 Buffer 直接进行底层数据操作。由于不经过数据 Buffer ,在文件系统层面就无需考虑数据一致性的问题,因此,读写操作可以并行执行。

在最终进行数据存储的时候,所有操作都会串行执行, CIO 把这个事情交个了底层的 driver 。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值