本文为《大话存储》的读书笔记。

计算机的IO世界

总线

总线的概念

计算机中所有的IO都通过共享总线的方式来实现。

总线实际上就是一条或多条的物理导线。密密麻麻的印到电路板上,而且为了避免高频振荡的干扰,一般都会分组印刷到不同的电路板上,然后压合起来。

总线的分类

image.png

PCI总线是目前x86服务器普遍使用的南桥与外设连接的总线技术。

PCI总线的地址总线和数据总线是分时复用的,这样可以节省管脚数量。

在数据传输时,PCI协议上有三种不同的角色

  • 主,也就是发起者
  • 从,Target或者Slave
  • 仲裁者Arbiter

CPU、内存、磁盘交互过程

下面我们来介绍一下CPU、内存、磁盘交互过程

CPU、内存、磁盘通过总线相互连接,所以通路的因素具备了。

然后需要上通路上的设备有不同的标识,这样才可以区分开。所以每个IO设备在启动的时候,都需要向物理机的内存中映射一个地址。

接下来是的过程。

CPU首先将IO地址放到系统总线上,接下来传三条指令

  • 是想读还是想写,是否开磁盘缓存等。
  • 从哪儿读:磁盘的LBA地址
  • 读到地址放到内存那里?
    通过总线传到磁盘控制器上。

接着磁盘控制器主要做:

  • 查找并寻道
  • 通过DMA技术,也就是磁盘控制器可以直接对内存寻址并进行写操作。(这样可以解放CPU)

上述所说的过程均为CPU对磁盘发送某种指令的信息,告诉磁盘控制器应该怎么操作。而这一类的指令可以分为SCSI指令集和ATA指令集。SCSI指令集更高效。

所以所谓SCSI指令集其实就是CPU告诉磁盘控制器到底是想读还是想写,从磁盘的那个位置开始,有多长等关键信息的规范

image.png

磁盘原理

本章所提到的磁盘主要指的是机械磁盘。

要了解磁盘主要需要通过如下几个方面;

  • 磁盘的结构
  • 数据的组织方式
  • 高层技术:队列、无序存储、磁盘缓存
  • 磁盘接口技术
  • 磁盘驱动程序

为什么需要磁盘

CPU的速度比内存块100倍,比硬盘快100万倍,也就是说磁盘速度是相当的慢的,有人说整个系统的速度就是被磁盘拖慢的。确实如此,但是为什么还需要磁盘呢?

内存的速度虽然快,但是断电了怎么办,而且硬盘是以TB甚至TB计算的,内存如果达到这么大的容量,价格将不可想象。

我们可以憧憬一下,人类如果造出一个能断电存储、容量还得大、访问速度快最关键的要便宜的硬盘来,CPU就可以直接访问硬盘了。但是在这之间,我们还是必须容忍CPU-内存-硬盘速度不匹配的问题,这才引出了诸多的解决方案,比如用缓存、DMA、多线程等

磁盘的结构

image.png

磁盘主要由盘片、磁头、步进电机构成

  • 硬盘一般是多个盘片固定在一个公共的转轴
  • 主轴电机带动盘片组高速旋转产生高速气流,将磁头浮起;
  • 磁头组在电机的带动下作径向运动

通俗的说来,盘片上布满磁性介质,类似于一张白纸,如果想在上面记录的话,一般需要划格子,格子就是所谓的磁道。

因为盘片是圆的,所以就每个同心圆(磁道)就是类似于稿纸的一行,每一行上再分为若干的格子(扇区),磁头就类似于打印喷头

对于打印机来说,需要纸不断的移动,但是这样效率太低了,对于磁盘来说可以让磁盘不断的旋转,然后移动磁头来进行换行。

目前服务器中一般选择1万转/s,可以获得比较高的性价比。

  • 磁道:同心圆
  • 扇区:每个同心圆的上每段圆弧,是读写的最小单位
  • 柱面:所有盘面上的同一磁道,在竖直方向上构成一个圆柱。
  • 每个盘片上都有可以读写数据的磁头

需要注意的是,数据的读写是按照柱面来进行的,也就是说首先在同一柱面的内从0磁头开始,依次向下在同一柱面的不同盘面上进行操作。为什么会这样呢?因为这样操作只需要改变电流,只需要通过电子切换,而不需要改变磁道(机械切换),速度更快。

我们需要记住一个规律:把磁头挪到指定的磁道的速度是非常慢的。

扇区寻址

了解了磁盘结构以后,我们来看一下磁盘如何寻址。

我们可以把寻找磁盘里面的数据想象成在一个小区里面找某一户人家一样。我们需要知道三个信息:在哪一栋、哪一层、哪一户,然后就可以找到他了。同样,找磁盘上的数据可以通过柱面(哪一栋)、磁头(哪一层)、扇区(哪一户)找到某个数据。

但是这种编码方式比较的麻烦,不利于程序的编写。就比如一户人家在12栋3楼4号,并不直观。那么我们可以用一个线性地址120304来表示这户人家的地址,显然这种方法更利于编程。

所以我们可以将磁道磁头扇区与另一种线性地址对应起来,这种对应关系保存在磁盘控制电路的ROM里面,可以在磁盘初始化的时候载入缓存以便查询。

于是磁盘可以对外提供线性地址,即LBA(Logical block address)地址。可以将磁盘想象成只有一个磁道,是无限长的直线,扇区为上面的等长的线段,这样可以屏蔽柱面、磁头等比较复杂的东西,对外而言寻址方式更为简便。

也就是说通过磁盘控制器可以对外屏蔽查找具体扇区的细节,进行逻辑的抽象,这样就完成了物理地址到逻辑地址的抽象、虚拟、映射

磁盘高层技术

我们在前面的介绍中说过,磁盘进行磁道的切换最费时间,所以我们会通过多种方法来避免频繁的磁道切换。如下就是比较常用的解决方案。

队列技术

第一个指令向让读最外圈的数据,第二个指令向读最内圈的数据,第三个指令又向读最外圈的数据,如果按照这个顺序来,需要频繁的换道,我们知道换道时间非常长,是性能的瓶颈。

所以可以先切换到最外圈,执行完第一个指令,然后先执行第三个指令,最后再执行第二个指令,类似于电梯,每次把同方向的人都搭载上去。

无序传输技术

要求读某些扇区的内容,如果不做优化的话,肯定直接傻乎乎的从开头开始读。但是实际上,有可能磁头离数据段的末尾近啊。

那么我们完全可以无视读出数据的顺序,从离磁头近的扇区开始读。

磁盘缓存

磁盘的速度是相当慢的,所以与外界的内存、CPU的访问有极大的矛盾。就好比一个团队里面,有人做事快,有人做事慢,做事快的就会等做事慢的。

当然这种矛盾是无法调和的,那有什么折中的方法吗?有,有句话叫笨鸟先飞,所谓缓存就是笨鸟先飞。

比如说做事慢的人,虽然手脚不麻利,但是有个好处,记忆力好,而且勤奋。所以当事来了以后,他虽然没办法立刻给答复,但他可以先记住啊,然后告诉做事快的人先去忙。同样,他也可以提前把一些事先做了,然后准备着。避免手忙脚乱。

回到磁盘上,缓存其实就是一块电路板上的RAM芯片,他的速度就很快,而且如果断电的话,里面的数据会丢失。

缓存的主要的作用是:

  • 接收指令和数据
  • 进行预读

有些资料说禁用磁盘缓存,这种说法容易造成误解。

实际上禁用磁盘缓存就是Write Through(直通)模式,也就是说磁盘收到指令和数据并需要进行写入的时候,不是在数据到达缓存的时候就返回成功,而是应该等到数据都落入盘片以后,才向控制器返回成功信号。相当于禁用了缓存

实际上这种模式,数据还是会到达缓存。
SCSI指令中有两个参数可以控制缓存:

  • DPO(Disable PageOut):禁止缓存中的数据页被换出,置了这个位的数据不能将其他数据换出。
  • FUA:Force Unit Access:强制盘片访问,也就是Write Through

所以如果DPO和FUA都置1了, 相当于完全不使用缓存的提速作用。

image.png

影响磁盘性能的因素

  • 转速:主要影响连续IO的吞吐量。因为转得越快,数据传输时间越短。
  • 寻道速度:主要影响随机IO。因为随机IO下,必须频繁的换道。
  • 单碟容量:单碟容量越高,单位空间内的数据量越大
  • 接口速度:最不重要,因为目前的接口速度已经满足了磁盘能达道的最高传输带宽。

磁盘接口技术

不管硬盘内部多么复杂,一定需要向使用者提供接口,以屏蔽访问的细节,这个接口不是物理的接口,而是硬盘面向外部的时候,为了被方便的使用,所提供的抽象的协议。

目前硬盘提供的物理接口

  • 用于ATA指令的IDE接口
  • 用于ATA指令的SATA接口
  • 用于SCSI指令的并行SCSI接口
  • 用于SCSI指令的串行SCSI(SAS)接口
  • 用于SCSI指令系统,并且承载于FC协议的串行FC接口

列成表格如下

接口 英文 指令系统 备注
IDE接口 Parallel ATA(Advanced Technology Attachment) ATA指令系统 Integrated Drive Electronics
SATA接口 Serial ATA ATA指令系统
并行SCSI接口 Parallel SCSI(small computer system interface) SCSI指令系统
SAS接口 serial SCSI SCSI指令系统
FC接口 Fibre Channel SCSI指令系统 承载FC协议的串行SCSI接口

IDE硬盘接口

IDE,integrated Drive Electronics ,电子集成驱动器,本意是把控制电路、盘片、磁头放到一个容器中的硬盘驱动器,制造比较容易。

IDE接口,也称PATA接口,也即并行ATA

ATA协议需要主机更多参与IO,无法支持大量的并发访问,适用于家用电脑和低端服务器;

SATA硬盘接口

SATA:串性ATA,用串行线路传输数据,但是指令集仍然是ATA。

下图是IDE与SATA线缆的对比

image.png

SATA的优点是:

  • 可以对指令及数据包进行CRC,而PATA只能对来回传输的数据进行较验。
  • 相对于IDE的80芯更节省空间。

目前SATA规范中接口速率为6Gb/s,有于SATA使用8bit/10bit编码,所以6Gb/s相当于600MB/s的接口速率,但是实际上性能没有得到多大的提升。

因为硬盘的速率瓶颈在于硬盘内部的寻道,而非传输,接口速率的提高最直接影响从缓存中的读写。

SCSI硬盘接口

SCSI接口更为灵活,而且性能也较高。

可以有8个或者16个SCSI设备连接在SCSI通道上,缺点是比较贵。因为一般需要配备价格不菲的SCSI卡,而且SCSI接口的设备在安装、设置时比较麻烦。

SCSI总线连接图:
image.png

一条总线上最多16个节点,各分配一个SCSI ID ,其中SCSI控制器需要占一个ID

SCSI卡上有一块类似CPU的芯片可以对SCSI设备进行控制,减少了CPU的负担,所以适合大量并发访问场景,适用于企业级数据中心

SCSI卡将SCSI总线上的设备,经过PCI总线传递给内存中运行的SCSI卡的驱动程序让OS知道所有设备。

下图是SCSI总线与计算机总线的连接图

image.png

可以看出SCSI卡一端接主机的PCI,一端用SCSI控制器接入SCSI总线。

多通道SCSI卡:如果一张卡上有多个控制器,每个控制器独立掌管一条总线

多通道SCSI控制器卡示意图
image.png

SCSI协议寻址方式

SCSI协议的寻址方式按照“控制器——通道——SCSI ID —— LUN ID (logic unit number) ”。

一个主机IO总线上可以有多个控制器,每个控制器可以有多条后端的SCSI总线(通道),每个SCSI总线上挂着8个或者16个SCSI设备,通过SCSI ID来区分。

然而SCSI ID不是最后一层地址,还有一个LUN ID 。 SCSI设备不能物理上再分割了,所以只能在逻辑上分,每个SCSI ID下面可以区分出若干的LUN ID 。这样一条SCSI总线上可接入的逻辑存储单元数量大大增加。

LUN对于传统的SCSI总线意义不大,但是对带RAID功能的SCSI接口磁盘阵列来说,因为会产生很多虚拟磁盘,所以可以使用LUN来扩充可寻址范围。习惯上称磁盘阵列生成的虚拟磁盘为LUN。

SCSI控制器也是总线上的一个节点,不过优先级必须是最高的。

磁盘控制器、驱动器控制器电路、磁盘控制器驱动程序的区别

磁盘控制器

硬盘的接口:

  • 物理接口:硬盘接入磁盘控制器需要的接口
  • 逻辑接口:指令系统,指令集定义了“怎么样向磁盘发送数据和读数据”,这套指令集是由专门的芯片来生成,这就是磁盘控制器

磁盘控制器的作用:参与底层总线的初始化、仲裁过程,向驱动程序提供简单的接口。

所以驱动程序只需要将要读写的设备号、读写的初始地址、长度告诉控制器即可,其他的由控制器来完成

驱动器控制器电路

  • 驱动器控制电路:位于磁盘的驱动器上,负责驱动磁头臂来读写数据
  • 磁盘控制器:向磁盘驱动器的控制器电路发送指令。

所以流程是,CPU通过总线发送指令给主板上的磁盘控制器,
磁盘控制器通过线缆发送指令给驱动器
驱动器控制磁盘进行读写。

image.png

CPU操作磁盘控制器的指令系统叫磁盘控制器驱动程序
控制器收到指令通过电路逻辑运算生成的指令就是常说的ATA指令集或者SCSI指令集。

为什么在SCSI磁盘上安装操作系统需要手动加载SCSI驱动?

机器刚通电,OS还没启动起来,所以也没加载磁盘控制器驱动,如何访问磁盘的呢?

这要从机器启动的流程说起,系统的BIOS中存放了初始化系统的基本代码,所以机器启动后执行系统BIOS里面的代码,里面有一步就是去查找磁盘控制器上的BIOS地址,然后去这个地方再执行其中的代码以初始化控制器。

最后此BIOS让CPU提取0磁道中的第1扇区的代码,从而加载OS。

从上面的流程可以看出,系统BIOS会指示CPU查找磁盘控制器的BIOS地址,里面有最基本的磁盘控制器驱动程序。但是因为不完善,所以在OS内核启动的过程中,会用自己的驱动来接管。

那么向SCSI磁盘上安装OS,必须手动加载SCSI驱动就原因就不难解释了。

因为CPU必须通过执行驱动程序才能向磁盘驱动器发指令,而磁盘控制器BIOS里面的代码非常简单,功能很有限,只能适用于启动OS这种临时任务。所以必须加载完整功能的驱动程序。

对于ATA磁盘来说,ATA已经是非常成熟的技术了,控制器一般都是Intel的,所以操作系统安装程序在初始化执行的时候已经自行加载了驱动。

而SCSI磁盘的生产厂商很多,所以必须手动加载。

安装了OS的系统,启动之初从磁盘BIOS(ROM)中读取驱动程序,此时的执行速度很慢,但是一旦将OS本身的驱动程序读到了内存中以后,速度就可以增加。由于操作系统安装以后,就具有磁盘的驱动程序了,所以不需要每次手动加载。

image.png

磁盘IOPS和吞吐量

衡量磁盘的性能最重要的两个参数就是IOPS和吞吐量。

IOPS关注的就是每秒进行多少次的IO,跟随机读写的快慢有关。
而吞吐量关注的是硬盘在传输数据的时候数据流的速度。

IOPS

IOPS:也就是每秒能进行多少次IO。这个值也不是固定的。

写入10000个大小为1KB的文件,比写入一个10MB的文件耗费更多的时间。

因为10000个文件需要做好几万次IO,而写入10MB的大文件,因为是连续存放,所以只需要几十个IO。
对于写入10000个小文件,因为每秒需要的IO非常高,如果用具有较高IOPS的磁盘,将提速不少。写入10MB文件,就算用了较高的IOPS也不会提升速度。因为只需要少量的IO。只有用较大传输带宽的才会体现优势。

传输带宽

传输带宽:硬盘在传输数据时的数据流的速度。

在同一块硬盘写入不同大小的数据,带宽不同。

硬盘的带宽如果高,在传输大块的连续的数据时有优势。

而具有高IOPS的硬盘在传输小块的不连续的数据具有优势。

image.png

版权声明:本文为dy2903原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/dy2903/p/8366720.html