磁盘结构
磁盘性能:随机读 与 顺序读
磁盘碎片是什么?
什么是文件系统?
计算机是如何找到确定路径下的文件的?
前言
在学习kafka的时候,明白了log是kafka的核心,并且log是写在磁盘上的,我就有一个疑问:磁盘的速度不是很慢吗?为什么基于磁盘读写的kafka吞吐量这么大?MySQL不也是存储在磁盘上的吗,它是如何利用磁盘的特性加速存取过程的?
此外,上一篇文章文件描述符 写了关于进程与文件的关系,但这也仅限于此,inode之下还是一个黑盒子,希望通过这篇文章,打开潘多拉之盒。
磁盘
磁盘结构以机械磁盘为例,采用的是盘面旋转,多磁头从多盘面获取信息。越靠近主轴的磁道存储的扇区越小,存储的信息越少。单位时间内,磁盘的转速越快,能读取的信息越多。多磁头可以一次性的从磁柱读取多份信息。
磁盘读取性能磁盘读取时间 = 磁头摆动时间(seek time 5-15ms) + 磁盘转动时间(rotational delay 4-8ms) + 读取时间(transfer 25us)
磁盘顺序读写:因此我们可以知道,一次磁盘读写的大部分时间是用于磁道寻址与磁头摆动,而真正的读取数据时间很短。因此,绝大多数应用都是利用磁盘的顺序读写来提升性能。比如kafka,采用顺序写log的方式来记录各种数据,mysql利用顺序写来记录redo log 和 binlog。所以,它们的写入性能非常高,也就能支撑起大的吞吐量。
操作系统和应用系统需要把相关联的数据存储在临近的扇区以及同一磁柱上,这样也可以提升IO性能。相反,如果一个应用充斥着大量的随机IO,那么这个应用的性能一定是非常差的。
磁盘碎片:所谓的磁盘碎片就是逻辑上关联性强的数据被分布在跨度较大的存储区域(扇区),造成了很多随机IO,因此需要经常合并磁盘碎片,提高IO性能。
文件系统
文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。
简单来讲,就是文件系统封装了复杂的底层数据结构,向上提供了统一的封装,使得用户对数据的管理更加安全便捷。
因此,一个最重要的问题就是,数据在底层到底是怎么存储的?
不同的数据存储方式对比:
连续存储
连续块存储:这是一种最简单的实现方式,管理便捷。但最大的问题是空洞问题,即使物理磁盘还有空余容量,也不能再写入文件了。常见于CD-ROM等预先明确数据大小的存储器
链表式存储链表式存储:好处是不存在存储空洞且只需要记住第一个block的位置即可,缺点很明显:就是会造成大量的随机IO,而且读取完一个block才知道下一个block的位置,效率过低。为了改进这种效率问题,FAT诞生
FATFAT:链表式存储中,next指针是存储在每个block中的,而FAT把这些指针统一写在一个array中,这样获取一个文件的所有block位置就变得简单很多,效率也更高。但FAT也有一定的限制,比如FAT16只有65536个位置,FAT32虽然有更多的指针位,但是FAT表本身也占用了更大的内存。且FAT在读取某一文件中部时效率低,因为需要链表遍历。此外,FAT格式的文件系统不利于扩展文件的metadata。
Linux采用的inode格式I-Node:Linux 文件系统的思想是把所有与数据本身无关的data(如类型,大小,owner,创建修改时间等)都存进一个特殊的block中(inode),然后通过这个block可以找到与数据相关的所有block。
通过inode寻找所有与文件相关的block可以看到,每个inode都有12个直接block指针,假设每个block是4k,那么有48k的地址可以通过一次寻址直接找到,这对小文件的寻址速度有非常大的帮助,而文件系统中,绝大多数文件都是小文件,这样也就直接提高了文件系统的性能。如果有大文件,可以通过二次甚至三次间接寻址的方式来获取block地址,目的是能节省inode占用的空间,把更多的空间留给数据。
计算机是如何找到确定路径下的文件的?
inode寻址的例子
这里有一个比较清晰地例子表明,文件系统是如何将path转变为真正的block地址的。简而言之,inode树组成了目录树,通过树形查找获取磁盘信息。
网友评论