关于磁盘这章,有个大概的了解就可以了,不用太深究具体内容,比如 IOPS 的计算公式什么的,着重关注 MySQL 服务器优化这块。

磁盘访问模式

  • 顺序访问
    • 顺序地访问磁盘上的块。
    • 一般经过测试后,得到该值的单位是 MB/s,表示为磁盘的带宽,普通硬盘在 50~ 100 MB/s 之间。
  • 随机访问
    • 随机地访问磁盘上的块。
    • 也可以用 MB/s 进行表示,但是通常使用 IOPS(每秒处理 IO 的能力),普通硬盘在 100-200 IOPS 之间。

图片.png
文件系统的存储层是基于“块”来存储的,比如“*.mp4”的视频文件在磁盘上是通过一个一个磁盘块来存储的,如下图所示:
图片.png
如果我们在读取上面视频的时候是 1,2,3,4 这样顺序读的话,就称为“顺序访问”,如果是跳着读的话,就称为“随机访问”,两者的速度差距很大,“顺序访问”的速度要远远大于“随机访问”的速度。

所以我们常常发现,我们拷贝一个视频文件的话,速度很快,能达到几十M甚至几百M每秒,如果是拷贝一堆小文件的话,速度就很慢,因为它是“随机访问”。

数据库中访问数据属于随机访问,比如通过执行 select * from where id=1 or select * from where id=100 的 SQL 语句查询数据,它是随机访问的,MySQL 对数据的访问做了优化,把随机访问转成顺序访问。

IOPS(Input/output operations per second)

表示每秒随机访问 IO 的次数。

比如下图是 4K 随机写的速度,最下面一条数据 0.8M/s 对应的 IOPS 是如何计算的?

IOPS = 0.8 * 1024 / 4 = 204.8

  • 机械磁盘的 IOPS:100 ~ 200
  • 固态硬盘的 IOPS:50000+

磁盘(一) - 图3

IOPS 计算公式

对于磁盘来说一次完整的 IO 操作是这样进行的:当控制器对磁盘发出一个 IO 操作命令的时候,磁盘的驱动臂(Actuator Arm)带读写磁头(Head)离开着陆区(Landing Zone,位于内圈没有数据的区域),移动到要操作的初始数据块所在的磁道(Track)的正上方,这个过程被称为寻址(Seeking),对应消耗的时间被称为寻址时间(Seek Time);但是找到对应磁道还不能马上读取数据,这时候磁头要等到磁盘盘片(Platter)旋转到初始数据块所在的扇区(Sector)落在读写磁头正上方的之后才能开始读取数据,在这个等待盘片旋转到可操作扇区的过程中消耗的时间称为旋转延时(Rotational Delay);接下来就随着盘片的旋转,磁头不断的读/写相应的数据块,直到完成这次 IO 所需要操作的全部数据,这个过程称为数据传送(Data Transfer),对应的时间称为传送时间(Transfer Time)。完成这三个步骤之后一次 IO 操作也就完成了。

计算单次 IO 时间的公式:

IO Time = Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate

计算 IOPS 的公式:

IOPS = 1 / IO Time = 1 / (Seek Time + 60 sec / Rotational Speed / 2 + IO Chunk Size / Transfer Rate)

磁盘分类

HDD(Hard disk drive)


  • 传统磁盘,通过盘片旋转,磁头进行定位,读取数据
  • 顺序访问性能较好
    • 100M/s
    • 磁盘吞吐率
  • 随机访问性能较差
    • 需要磁头旋转定位
    • IOPS 较低
  • 常见转速(转速不会太高,散热跟不上)
    • 笔记本硬盘:5400 转/分钟
    • 桌面硬盘:7200 转/分钟
    • 服务器硬盘:10000 转/分钟,15000 转/分钟

根据磁盘的转速可以算出 IOPS 的理论值(忽略一些其他因素):转速 / 60,比如 15000 转/分钟,它的 IOPS 理论值是 15000/60=250 IOPS。

磁盘(一) - 图4

SSD(Solid-state drive)


  • 纯电设备
  • 由 FLash Memory 组成,Flash 分为 MLC 和 SLC,两者的主要区别是闪存的写入寿命,一般 SLC 是 MLC 10倍
    • MLC 闪存颗粒对一般企业的业务够用
    • SLC 闪存颗粒价格较贵,一般银行、军工企业会使用
  • 没有读写磁头
  • IOPS 高
    • 50000+ IOPS
    • 读写速度非对称,以 INTEL SSD DC-S3500 为例子
      • Random 4KB3 Reads: Up to 75,000 IOPS
      • Random 4KB Writes: Up to 11,500 IOPS
      • Random 8KB3 Reads: Up to 47,500 IOPS
      • Random 8KB Writes: Up to 5,500 IOPS
  • Endurance Rating
    • 表示该 SSD 的寿命是多少
    • 比如 450TBW,表示这个 SSD 可以反复写入的数据总量是 450T(包括添加和更新)

为什么 SSD 的读写速度是非对称的?

SSD 也是由一个一个块组成的,不同的是,HDD 的扇区大小是 512字节,而 SSD 是 4K 大小,刚买了的 SSD 是空白的,没有写入任何数据,数据可以直接写入,SSD 使用了一段时间之后,各个块都已经存在数据了,这个时候我们要更新数据了,它会先执行擦除,再写入数据,Flash 在擦除的时候是使用区为单位的,一个区的大小是 128K 或者 256K,所以 SSD 的读写速度是非对称的。

提升 IOPS 性能的手段

  • 通过 RAID 技术
    • 功耗较高
    • IOPS 在2000左右
  • 通过购买共享存储设备
    • 价格非常昂贵
    • 但是比较稳定
    • 底层还是通过 RAID 实现
  • 直接使用 SSD
    • 性能较好的 SSD 可以达到万级别的 IOPS
    • 建议可以用 SSD + RAID5,RAID1+0 太奢侈

RAID 类别

RAID0
image.png

  • 速度最快
  • 没有冗余备份

RAID1
image.png

  • 可靠性高
  • 读取速度理论上等于硬盘数量的倍数
  • 容量等于一个硬盘的容量

RAID5
image.png

  • 至少要3块硬盘
  • 通过对数据的奇偶检验信息存储到不同的磁盘上,来恢复数据,最多只能坏一块
  • 属于折中方案

RAID6
image.png

  • 至少是4块硬盘
  • 和 RAID5 比较,RAID6 增加第二个独立的奇偶校验信息,写入速度略受影响
  • 数据可靠性高,可以同时坏两块
  • 由于使用了双校验机制,恢复数据速度较慢

RAID1+0
image.png

RAID5+0
image.png

RAID 卡

BBU(Battery Backup Unit)

  • 目前几乎所有 RAID 卡都带 BBU
  • 需要电池保证写入的可靠性(在断电后,将 RAID 卡内存中的缓存的数据刷入到磁盘)
  • 电池有充放电时间(30天左右一个周期,充放电会切换成 Write Through,导致性能下降,可以强制开启 Write Backup)
    • 使用闪存(Flash)的方式,就不会有充放电性能下降的问题

RAID 卡缓存

  • Write Backup(强烈建议开启缓存)
  • Write Through(不使用缓存,直接写入)
  • 写缓存并非默认开启,需要手动开启 Write Backup

LSI-RAID 卡相关命令

  • 查看电量百分比

    1. [root@test_raid ~]# megacli -AdpBbuCmd -GetBbuStatus -aALL |grep "Relative State of Charge"
    2. Relative State of Charge: 100 %
  • 查看充电状态

    1. [root@test_raid ~]# megacli -AdpBbuCmd -GetBbuStatus -aALL |grep "Charger Status"
    2. Charger Status: Complete
  • 查看缓存策略

    1. [root@test_raid ~]# megacli -LDGetProp -Cache -LALL -a0
    2. Adapter 0-VD 0(target id: 0): Cache Policy:WriteBack, ReadAdaptive, Direct, No Write Cache if bad BBU

    文件系统和操作系统

  • 文件系统

    • 推荐 xfs 和 ext4
    • noatime(不更新文件的 atime 标记,减少系统的 IO 访问)
    • nobarrier(禁用 barrier,可以提高性能,前提是使用 write backup 和使用 BBU)
  • 操作系统
    • 推荐 Linux 操作系统
    • 关闭 swap
    • 磁盘调度算法设置为 deadline

MySQL 服务器优化建议

  • 服务器硬盘建议都使用 SSD 固态硬盘,上线之前 SSD 需要经过严格的压力测试(一周时间),确保性能平稳
  • 查看磁盘针对不同大小页的 IOPS 性能,对比发现 4K 的性能要优于 8K 的性能,所以当使用 SSD 时,建议数据库页大小设置成 4K 或者是 8K,innodb_page_size=8K
  • SSD 磁盘调度算法设置为:deadline 或者 noop,deadline 适合数据库这种应用场景
    • echo deadline > /sys/block/sda/queue/scheduler deadline 适用于数据库,HDD 也建议改成 deadline
  • MySQL 参数设置(在 InnoDB 部分会讲到)
    • innodb_log_file_size=4G 该参数设置的尽可能大
    • innodb_flush_neighbors=0 性能更平稳,且至少有 15% 的性能提升

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/dd521p 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。