磁盘那点事
HULK虚拟化团队 360云计算
女主宣言
本文章是HULK虚拟化团队的存储小分队对磁盘的历史演变做的一个小结,存储作为一个云计算中非常重要的模块,更多的时候大家都集中在怎么用的基础上,对磁盘的一些历史或者基础性概念的由来不太清楚,希望本文能给大家一点启发。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
今天我们来聊聊磁盘,不多说先上一张图:
有人知道这是什么东东么?好吧,这是一个暴露年龄的问题,它叫温切斯特硬盘
1973年,IBM研制了一种新型的硬盘IBM334。这种硬盘拥有几个同轴的金属盘片,盘片上涂着磁性材料。它们和可以移动的磁头共同密封在一个盒子里面,磁头能从旋转的盘片上读出磁信号的变化,IBM把它称为温切斯特硬盘。
这就是我们今天使用的机械硬盘的祖先,可以叫它“元祖硬盘”,40多年过去了,计算机硬件发生了翻天覆地的变化,硬盘的存储容量也越来越大,但机械硬盘的结构没有大的变化,还是遵循这块“元祖硬盘”的设计。
结构组成
硬盘主要结构由三大块组成,磁盘片,电机马达,磁头臂。当然还有一些控制芯片和盘体。磁盘片是最终存储数据的地方,电机马达带动磁盘片高速运转,磁头臂上的磁头悬浮在磁盘表面,通过电机不停的移动来对磁盘进行读写,我们的数据就是这样记录到磁盘上的。
CHS
CHS就是Cylinder(柱面),Head(磁头),Sector(扇区)的简写,我们一般用CHS来计算磁盘的容量。
首先我们知道磁盘的盘片都是圆的,一个盘片被画成很多很多同心圆,每个同心圆就是一个磁道。
相邻磁道之间并不是紧挨着的,这是因为磁化单元相隔太近时磁性会相互产生影响,同时也为磁头的读写带来困难。一张1.44MB的3.5英寸软盘,一面有80个磁道,而硬盘上的磁道密度则远远大于此值,通常一面有成千上万个磁道。
每个磁道上再分成若干弧段,这些弧段就是扇区
好了,你现在知道扇区是什么了,那么你会不会有个疑惑,在一个盘片上,同心圆的周长会越来越小啊,那么是不是外面的磁道扇区就会很多,里面的磁道扇区会很小?
在早期的磁盘中,每个磁道的扇区数量是相同的,这一特性是外圈浪费了大量存储空间,现在的硬盘每个磁道扇区是不同的,越外面的越大,但是我们还是可以用固定扇区来计算容量,就像矩形的面积,最小扇区数+最大扇区数/2=平均扇区,一般认为操作系统中显示磁盘扇区数量为平均扇区
一块磁盘是有一堆同样大小的圆形磁盘组成,可以认为它们垂直的堆在一起,相同大小的同心圆(磁道),合在一起叫做柱面,每个柱面都有唯一编号,从最外面“0”开始。
再说说磁头,磁头主要作用是向磁盘写入数据,一个磁盘面正反两面都可写,磁盘面能否存储数据就取决于是否有磁头,只要有磁头,我们就认为有一个可写的盘面,所以计算容量的时候我们不算磁盘数量,只算有多少磁头就行了。
说到这里,你是否弄懂了柱面,磁头,扇区这些概念?
可以拿CD光盘想象一下,把光盘摞成一起,它就是硬盘,光盘上每个光圈就是磁道,一小段光圈就是扇区,大小一样的光圈和在一起就是柱面,在每个CD光盘上下各放一个针头就是磁头。
fdisk
下面我们使用fdisk命令在操作系统上看一下输出。
fdisk -lu /dev/sda
Disk /dev/sda: 214.7 GB, 214748364800 bytes
160 heads, 24 sectors/track, 109226 cylinders, total 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000308cc
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 419427839 209712896 83 Linux
下面这条输出说明这块磁盘设备有160个磁头,每个磁道有24个扇区,有109226个柱面,总共有419430400个扇区。
160 heads, 24 sectors/track, 109226 cylinders, total 419430400 sectors
我们看到每个扇区的大小是512bytes
Sector size (logical/physical): 512 bytes / 512 bytes
那么我们用CHS计算一下磁盘的容量
CHS=109226x24x160x512bytes=214.7GB。
512bytes
那么有人会有疑问,每个扇区512字节是固定大小么?还是每个机器都不一样?目前看来每个扇区512字节是一个不成文的规矩。
考虑到磁盘的性能,如果每个扇区1字节,那么写入大文件会频繁读写太多次,效率很慢,如果扇区太大又会造成空间的浪费,早期的磁盘容量不大,所以就将扇区大小设置为512字节。
随着硬盘容量越来越大,每个扇区512字节过于小了,比如4T的硬盘要分成无数个扇区,而且用户的文件也越来越大,都是以M,G来计算,每次读写512字节硬盘效率也不高。
这时候硬盘大厂Western Digital提出来,我们将扇区换成4096字节吧,并且使用Advanced Format做为标识。
如果你的硬盘上有Advanced Format标识,那就是4096字节扇区的。
但是这么改出现了一个大问题,因为512字节扇区成了不成文的规矩,在整个软件链中,基本输入/输出系统(BIOS)、引导装载程序、操作系统内核、文件系统代码和磁盘工具等工具全部都想当然的认为磁盘的每个扇区就是512字节,如果改成4096字节BIOS甚至都找不到引导分区,整个产业链都要为了硬盘个做出改变,这个成本是巨大的。
硬盘厂商为什么要改呢?一个是性能的考量,还有一个原因是扇区太多,硬盘固件检测和纠正扇区错误负担会非常重
硬盘厂商想出一个办法,使用固件将4096字节物理扇区分成512字节逻辑分区,做到对其它设备透明,这样当然皆大欢喜了,可是又出现了一个潜在的隐患4k对齐
4k对齐
造成4k不对齐主要原因就是操作系统认为我的磁盘是512字节扇区的,但是实际上设备可能是1024,2048,4096的,这个问题在ssd硬盘上也会显现,因为ssd和传统磁盘结构完全不一样,它实际上模拟了扇区这个概念,单位读写的大小和颗粒有关。
想象一下,如果写入一个4096字节数据,在4096扇区的磁盘上,因为文件系统数据和底层物理扇区正好一致,磁盘执行一次写入即可。
因为linux基本以8个扇区做为一个block来写,所以每次写入都是4096字节
那么如果操作系统格式化磁盘是从第三个扇区到最后一个扇区,那么写入4096字节在磁盘上就有可能会跨扇区,造成两次写入,导致性能下降。
所以使用新型硬盘的时候,我们要注意是否4k对齐,只要扇区起始能被8整除,基本就是4k对齐的了。
比如上面的命令显示是从2048扇区开始,此磁盘是4k对齐的。
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 419427839 209712896 83 Linux
那么有人会问,能被8整除的数很多,为什么从2048开始?不是512,1024?
前面的2048个扇区(1MB)被保留做为分区表和其它用途,在linux中0号扇区是MBR和分区表,1到2047则为grub保留,虽然grub一般只用其中几十个扇区。
结尾
看到这里,你是不是对磁盘又有了进一步了解?磁盘那点事就先聊到这,下回见。