不得不说,关于磁盘的各种概念网上说法很多,看了半天快把我看晕了,最后总结了总结,基于我的认知基本理顺了。
顺序 和 随机
磁盘的顺序访问和随机访问是怎么定义的呢?如果一次IO操作起始的逻辑块地址logical block address (LBA)紧挨着上一次IO操作的终止 LBA,就是顺序访问,否则就是随机访问。下边这个图比较形象(
https://en.wikipedia.org/wiki/IOPS)。
逻辑地址是程序中认识的块地址,编号顺序递增。除了 LBA 还有 PBA(物理块地址),一般逻辑和物理地址会有一个对应关系。物理地址就是数据在磁盘上的实际地址了。
Throughput
吞吐率,是指顺序从磁盘读取数据时候,能达到的最大传输速度,通常单位是 MB/s。衡量大数据量的传输效率基本都用吞吐率。这个应该是单线程统计的。
latency
是一次操作的耗时,一般指发送请求到返回结果的时间,从磁盘角度看,不仅包括定位数据,还包括数据传输的时间。latency这个词本身并没有规定要访问多大的数据量。
IOPS
IOPS是每秒执行的操作数量,一般测的是随机访问,各种硬盘厂商声称硬盘的IOPS相当高,但是实际用的时候不是那么回事。因为这个东西依赖latency和工作负载,比如一次操作访问数据量的大小,等待队列中的读写请求数等。1998年 Intel 公布了一个开源的测IOPS的工具,叫 Iometer,说你们都别自己玩了,咱们统一都用这个比,就是定了个 benchmark,现在一般都用这个测。
HDD
HDD 就是 Hard Disk Drive,硬盘驱动器,也就是普通的机械硬盘,通过磁头读写数据。HDD 的随机访问和顺序访问是有区别的。
把磁盘看成一个光盘,上边有一个磁头用来写东西,就像钢笔头一样,要在一个位置写东西,需要先将磁头移动到那个位置,这个操作叫seek(旋转+寻道),接下来就是将数据顺序写下去(write)。写完数据之后磁头自动向后移动,如果继续挨着写就不需要 seek 了。
举个例子,以一个汉字为单位,那么顺序写一句话 “小孩儿你好呀”,只需要将磁头 seek 一次到“小”要写的位置,然后 write “小”,接下来直接把“孩儿你好呀” 一个个 write 到后边就可以了,这些字在磁盘上都存在了一起。随机写就是把这几个字分开存,互相不挨着。那么共需要 6 次 seek,6次 write。顺序写总是比随机写要好的,因为随机写多了 5 次 seek 的时间。
一个 HDD 的 seek 耗时是 10ms,吞吐率是 100MB/s,也就是每秒能 write 100MB 的数据。那么以 1KB 为单位,纯 write 这 1KB 的数据只需要 10us ,是seek 的 1/1000。 可以看到 seek 是很不友好的。
由于HDD 可以覆盖写,所以 LBA 和 PBA 是一一对应的,连续的逻辑地址也对应了连续的物理地址,所以有随机访问和顺序访问的区别。
SSD
SSD 是固态硬盘,solide-state drive,超快的那种。下图是 Intel 给出的一款 SSD 的性能指标(
https://ark.intel.com/compare/97161,97162,187933,187936)
顺序访问和随机访问本来就没啥可比性,取决于每次随机访问的数据量大小。所以他这也没用同一个单位。
为啥写的慢呢,得看 SSD 的结构了,SSD 是个三层次,最高层是 NAND Flash,每个 NAND Flash 里有多个 Block ,Block 里又包括很多 Page,SSD 的特点就是读和写都要以 Page 为单位,最少一个 Page。通常一个 Page 是 4k 或 8k。不能覆盖写 page,要覆盖必须清空那个 page 所在的 Block。亦或者要先将这个 page 所在块的数据移动到另一个被擦除的 block里。所以写比较麻烦。
因为这些结构的设计,SSD 上连续的一段 LBA 不一定对应连续的 PBA ,SSD 用一个闪存转换层 Flash Translation Layer(FTL)将这个映射管理起来了。所以,SSD 的顺序写和随机写没有区别。可以当成 SSD 都是随机访问数据的。