作者:yanfei,腾讯后台架构师,参与项目为搜搜网页开发和搜搜开放平台。
?
关于文件系统,相信大家都不陌生。身为攻城狮的我们几乎天天都会与之打交道,但是细深剖一下,其中又有多少是我们理解深度不够的呢。那么让我们一起来看一下下面这一组Linux文件系统相关的问题吧:
1、机械磁盘随机读写时速度非常慢,操作系统是采用什么技巧来提高随机读写的性能的?
?
2、touch一个新的空文件占用磁盘空间吗? 占用的话占用多少?
?
3、新建一个空目录占用磁盘空间吗?占用多少?和新建一个文件相比,哪个占用的更大?
?
4、你知道文件名是记录在磁盘的什么地方吗?
?
5、文件名最长多长?受什么制约?
?
6、文件名太长了会影响系统性能吗?为什么会产生影响?
?
7、一个目录下最多能建立多少个文件?
?
8、新建一个内容大小1k的文件,实际会占用多大的磁盘空间?
?
9、向操作系统发起读取文件2Byte的命令,操作系统实际会读取多少呢?
?
10、我们使用文件时要怎么样来能提高磁盘IO速度?
?
如果你能想也不用想的就回答上来百分八十的问题,那么请关掉本篇文章吧。如果不能,而且你也像作者一样对有窥探操作系统隐私的嗜好,那么就请随我一起来探索文件系统的这些有趣的地方,相信理解了这些之后对我们手中的工作会有很大的帮助。
?
一、磁盘构成及分区
?
1、磁盘物理结构
?
还是先从最基本的磁盘物理结构说起吧,注意本文只讨论机械磁盘,SSD不在本文讨论范围之内。我们人类管理任何事物总是习惯先划分 出一定的结构,再此规则的基础上进行管理。军队分军、师、旅、团和营。公司分事业群、部门、中心和小组。,然后。对于管理磁盘,分磁盘面、磁头、磁道、柱 面和扇区。
?
??? 磁盘面:磁盘是由一叠磁盘面组成,见下左图。
?
??? 磁头(Heads):每个磁头对应一个磁盘面,负责该磁盘面上的数据的读写。
?
??? 磁道(Track):每个盘面会围绕圆心划分出多个同心圆圈,每个圆圈叫做一个磁道。
?
??? 柱面(Cylinders):所有盘片上的同一位置的磁道组成的立体叫做一个柱面。
?
??? 扇区(Sector):以磁道为单位管理磁盘仍然太大,所以计算机前辈们又把每个磁道划分出了多个扇区,见下右图
?
?
?
?
?
?
本人爱上Linux的一个原因就是只要你愿意下功夫,你就能把Linux的外衣一脱到底,满足你的一切欲望(请想歪的骚年去面壁)。Linux上可以通过fdisk命令,来查看当前系统使用的磁盘的这些物理信息。
?
?
?
?
?
?
以上是我本人的一台虚拟机的磁盘物理信息。可以看出我的磁盘有255个heads,也就是说共有255个盘面。3263个 cylinders,也就是说每个盘面上都有3263个磁道, 63sectors/track说的是每个磁道上共有63个扇区。命令结果也给出了Sector size的值是512bytes。那我们动笔算一下该磁盘的大小吧。
255盘面? * 3263柱面 * 63扇区 * 每个扇区512bytes = 26839088640byte。
结果是26.8G,和磁盘的总大小相符(至于fdisk给出的详细结果相差了约4M的大小,笔者也没有弄彻底明白,有兴趣的读者可以继续研究)。
另外查看了其它两台机器的磁盘情况,发现个有意思的事情。如下图,无论磁盘的容量大或者是小,其磁头数和每磁道扇区数都是不变的,只是磁道变多了而已。
?
?
2、分区
分区是操作系统对磁盘进行管理的第一步,这也是我们任何一个计算机使用者都非常熟悉的概念。例如Windows下的C、D、E、F盘。那么请思考一下,
??? 思考:前面的磁盘的详细物理结构已经有了,如果让你把整块磁盘分成C、D等分区,你会怎么分呢??
??
方案一: 255个盘面,C盘是0-100盘面, D盘是101-200个盘面,……
方案一: 255个盘面,C盘是0-100盘面, D盘是101-200个盘面,……
方案二:3263个柱面,C盘0-1000个柱面,D盘1001-20001个柱面,……
对于以上的两个方案,你会选择哪一种呢??先说下磁盘IO时的过程。第一步,首先是磁头径向移动来寻找数据所在的磁道。这部分时间 叫寻道时间。第二步,找到目标磁道后通过盘面旋转,将目标扇区移动到磁头的正下方。第三步,向目标扇区读取或者写入数据。到此为止,一次磁盘IO完成, 故:
单次磁盘IO时间 = 寻道时间 + 旋转延迟 + 存取时间。
对于旋转延时,现在主流服务器上经常使用的是1W转/分钟的磁盘,每旋转一周所需的时间为60*1000/10000=6ms,故 其旋转延迟为(0-6ms)。对于存取时间,一般耗时较短,为零点几ms。对于寻道时间,现代磁盘大概在3-15ms,其中寻道时间大小主要受磁头当前所 在位置和目标磁道所在位置相对距离的影响。
其实采用哪一种,最主要看的是那种方式性能更快。因为同一分区下的数据经常会一起读取,假如采用第一种,那么这样磁头就需要在 3000多个track间不停地跳来跳去,这样磁盘的寻道时间就会翻倍,磁盘性能就会下降。而对于方案二,假如对于磁盘C,只需要在磁头在1-1000个 磁道间移动就可以了,大大降低了寻道时间。(实际上分区并不是从0开始的,磁盘的第一个磁道对应的柱面会被用来安装引导加载程序以及磁盘分区表)。所以, 方案二的分区方式可以降低磁盘IO时间中的寻道时间部分,所以所有的操作系统采用的都是方案二,没有用方案一的。
??? 在Linux下使用过fdisk进行分区的话可以注意到以下信息。
?
?
?
这充分证明了操作系统是采用方案二的。
回到开篇问题1,操作系统是采用什么技巧来降低随机读写的性能问题的呢?操作系统通过按磁道对应的柱面划分分区,来降低磁盘IO所花费的的寻道时间 ,进而提高磁盘的读写性能。
二、 目录与文件
1、引子???
好了,磁盘基础都说完了,那我们正式进入主题,开始我们Linux文件系统相关的讨论吧。文件系统不就是目录和文件吗?这二位可是我们熟悉的不能再熟