选择硬盘

机械硬盘 (HDD)

一种传统的普通硬盘,主要由、磁头、盘片转轴、控制电机、磁头控制器、数据转换器、接口、缓存等组成。机械硬盘中的所有盘子都安装在旋转轴上,每个盘子平行。每个盘子的存储面上都有一个磁头。磁头和盘子之间的距离小于头发的直径。所有磁头都连接在磁头控制器上,磁头控制器负责每个磁头的运动。磁头可以沿着盘子的半径移动,加上盘子每分钟几千转的高速旋转,磁头可以定位在盘子的指定位置读写数据。作为精密设备,灰尘是其大敌,必须完全密封。

  • HDD 硬盘价格便宜,性能稳定,速度不快,磁盘损坏(开启磁盘日志)可以恢复数据。

固态硬盘 (SSD)

固态硬盘采用芯片存储方案,内部无磁头,不怕碰撞、冲击、振动,具备超强的抗震能力。

  • SSD 硬盘价格偏贵,速度非常快,磁盘寿命短。

PCIe存储设备

PCI-Express(peripheralcomponentinterconnectexpress)是一种高速串行计算机扩展总线标准,它原来的名称为“3GIO”,是由英特尔在2001年提出的,旨在替代旧的PCI,PCI-X和AGP总线标准。

  • 高速大容量的存储设备

黑科技Flashcache

Facebook最初开发的内核模块,它基于内核的 devicemapper 机制,允许将 SSD 设备映射为机械存储设备的缓存,堆叠成为一个虚拟设备供用户读写,从而在一定程度上兼顾 SSD 的高速与机械存储设备的高容量,更加经济高效地支撑线上业务。它可以在四种不同模式下工作:write-throughwrite-aroundwrite-backwrite-only。Write-around 和 write-through缓存在设备移除和重新引导后并不持久。大多数时候,我们需要缓存读写工作负载,因此我们使用了write-back模式。

  • 将SSD存储给机械磁盘提供热快数据缓存,解决了机械磁盘读取速度慢,也利用SSD速度性能。

Linux文件系统

  • EXT3

ext 3 是第三代扩展文件系统(Third extended filesystem,ext 3),同时也是一个日志文件系统,常用于 Linux 操作系统。

  • EXT4

ext 4 是第四代扩展文件系统(Fourth extended filesystem,ext 4)是 Linux 系统下的日志文件系统,也是 ext 3 文件系统扩展的结果。

  • XFS

XFS 是一种高性能的日志、文件系统。CentOS 7以后默认XFS,XFS 文件系统最大可以支持 18EB 的存储空间,并且可以创建最大为9EB 的文件,这是 Linux 原生文件系统 ExtX 所无法企及的。

  • BTRFS

Btrfs 属于 COW(写时复制)文件系统,同时也被称为 B 树文件系统,由 Oracle 公司研发。

随机IO和顺序IO

对于从磁盘中读取数据的操做,叫作IO操做:

  • 随机IO:假设咱们所须要的数据是随机分散在磁盘的不一样页的不一样扇区中的,那么找到相应的数据须要等到磁臂(寻址做用)旋转到指定的页,而后盘片寻找到对应的扇区,才能找到咱们所须要的一块数据,一次进行此过程直到找完全部数据,这个就是随机IO,读取数据速度较慢
  • 顺序IO:假设咱们已经找到了第一块数据,而且其余所需的数据就在这一块数据后边,那么就不须要从新寻址,能够依次拿到咱们所需的数据,这个就叫顺序IO,读取数据速度很快

因此:

  • 为什么日志是顺序io而innodb数据文件不是?

日志的写入是顺序追加的,而文件的写入通常包括写数据(写聚簇索引)、写索引(普通索引)。所以一般不可能在同一个文件中顺序写入。

  • 一个磁盘里多个进程写多个大文件,日志还是顺序读写吗?

对于单独一个文件来说,依旧是顺序写。如果进程够多,整体的写入仍然随机,性能也并不会提升很多。

  • 如果MySQL Innodb和日志一样只增加不修改不删除,它会是顺序写吗?

如果你指的是innodb引擎,仍然不会是完全的顺序写,因为要写数据和索引。如果你有自增主键数值类型,并且没有其他索引的情况下,这个会好很多,因为自增主键会保证写入的多在B+树的最右侧,同时写入的尽量在一个page内

  • 顺序/顺序读、随机写/读 并不必然是同时出现。比如RocksDB的引擎,因为结构是LSM树,所以写入是顺序的,但是读取并不是。

选择磁盘队列调度策略

Linux提供了cfq, deadlinenoop三种调度策略

  • cfq:这个名字是Complete Fairness Queueing的缩写,它是一个复杂的调度策略,按进程创建多个队列,试图保持对多个进程的公平(这就没考虑读操作和写操作的不同耗时)
  • deadline: 这个策略比较简单,只分了读和写两个队列(这显然会加速读取量比较大的系统),叫这个名字是内核为每个I/O操作都给出了一个超时时间
  • noop: 这个策略最简单,只有单个队列,只有一些简单合并操作

  • deadlinenoop差异不是太大,但它们俩与cfq差异就比较大

  • MySQL这类数据存储系统不要使用cfq
  • 时序数据库可能cfq会有所不同,不过也有说从来没见过deadlinecfq差的情况
  • 对于虚拟机上面的磁盘,建议采用比较简单的noop,毕竟数据实际上怎么落盘取决于虚拟化那一层
  1. # CentOS 查看磁盘队列调度策略; 发现默认的是 mq-deadline
  2. dmesg | grep -i scheduler
  3. # [ 0.064392] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
  4. # [ 0.618729] io scheduler mq-deadline registered
  5. # [ 0.618736] io scheduler kyber registered
  6. # [ 0.618895] io scheduler bfq registered
  7. # 修改调度策略
  8. grubby --update-kernel=ALL --args="elevator=deadline"
  9. # *需要重启
  10. reboot