在资料库优化和储存规划过程中,总会提到 IO 的一些重要概念,在这里就详细记录一下,对这个概念的熟悉程度也决定了对资料库与储存优化的理解程度,以下这些概念并非权威文件,权威程度肯定就不能说了。
读/写 IO,最为常见说法,读 IO,就是发指令,从磁碟读取某段扇区的内容。指令一般是通知磁碟开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读,还是写。磁碟收到这条指令,就会按照指令的要求,读或者写资料。控制器发出的这种指令+资料,就是一次 IO,读或者写。
大/小块 IO,指控制器的指令中给出的连续读取扇区数目的多少,如果数目很大,比如 128,64 等等,就应该算是大块 IO,如果很小,比如 1, 4,8 等等,就应该算是小块 IO,大块和小块之间,没有明确的界限。
连续/随机 IO,连续和随机,是指本次 IO 给出的初始扇区地址,和上一次 IO 的结束扇区地址,是不是完全连续的,或者相隔不多的,如果是,则本次 IO 应该算是一个连续 IO,如果相差太大,则算一次随机 IO 。连续 IO,因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或换道时间极短;如果相差太大,则磁头需要很长的换道时间,如果随机 IO 很多,导致磁头不停换道,效率大大降底。
顺序/并发 IO,这个的意思是,磁碟控制器每一次对磁碟组发出的指令套(指完成一个事物所需要的指令或者资料),是一条还是多条。如果是一条,则控制器 WordPress 加速缓存中的 IO 伫列,只能一个一个的来,此时是顺序 IO;如果控制器可以同时对磁碟组中的多块磁碟,同时发出指令套,则每次就可以执行多个 IO,此时就是并发 IO 模式。并发 IO 模式提高了效率和速度。
IO 并发机率。单盘,IO 并发机率为 0,因为一块磁碟同时只可以进行一次 IO 。对于 raid0,2 块盘情况下,条带深度比较大的时候(条带太小不能并发 IO,下面会讲到),并发 2 个 IO 的机率为 1/2 。其他情况请自行运算。
IOPS 。一个 IO 所用的时间=寻道时间+资料传输时间。 IOPS=IO 并发系数/(寻道时间+资料传输时间),由于寻道时间相对传输时间,大几个数量级,所以影响 IOPS 的关键因素,就是降底寻道时间,而在连续 IO 的情况下,寻道时间很短,仅在换磁轨时候需要寻道。在这个前提下,传输时间越少,IOPS 就越高。
每秒 IO 吞吐量。显然,每秒 IO 吞吐量=IOPS 乘以平均 IO SIZE 。 Io size 越大,IOPS 越高,每秒 IO 吞吐量就越高。设磁头每秒读写资料速度为 V,V 为定值。则 IOPS=IO 并发系数/(寻道时间+IO SIZE/V),代入,得每秒 IO 吞吐量=IO 并发系数乘 IO SIZE 乘 V/(V 乘寻道时间+IO SIZE)。我们可以看出影响每秒 IO 吞吐量的最大因素,就是 IO SIZE 和寻道时间,IO SIZE 越大,寻道时间越小,吞吐量越高。相比能显著影响 IOPS 的因素,只有一个,就是寻道时间。
目前磁碟都是机械方式运作的,主要体现在磁碟读写前寻找磁轨的过程。磁碟自带的读写 WordPress 加速缓存大小,对于磁碟读写速度至关重要。读写速度快的磁碟,通常都带有较大的读写 WordPress 加速缓存。磁碟的寻道过程是机械方式,决定了其随机读写速度将明显低于顺序读写。在我们做系统设计和实现时,需要考虑到磁碟的这一特性。
FastDFS 是一个开源的高效分散式档案系统,它最初的实现,档案是按 hash 方式随机分布到多个目录中的,后来增加了顺序存放的做法。通过对比测试,发现档案按目录顺序储存,写档案 IO 效率明显高于按目录随机储存。
目前磁碟顺序读取的速度并不差,比如普通硬碟的 IO 可以达到每秒 40~60MB,好一些的硬碟可以达到每秒 100MB 左右。在多程序或多执行绪并发读取磁碟的情况下,随著并发数的增加,磁碟 IO 效率将大大下降。主要是因为每次读写,磁轨可能存在较大的偏移,磁轨定址时间加大,导致磁碟 IO 效能急剧下降。对于这种场景,优化方案是尽可能减少并发读写的程序数或执行绪数。可以用锁的机制,也可以采用专门的磁碟 IO 执行绪来对磁碟进行读写。 FastDFS 2.x 版本,磁碟读写就采用了专门的执行绪来完成。
为了充分发挥多块磁碟的效率,不建议使用传统的 RAID 方式。比较好的做法是每块磁碟单独 mount,通过程式来控制对多块磁碟进行并发读写。采用单盘 mount,档案的备份和冗余可以通过多台机器实现。
档案数多了之后,比如达到上千万个档案,当随机访问众多档案时,档案系统的效能会急剧下降。业界流行的做法是将多个小档案合并储存到一个大档案中的方式来降低档案数。 FastDFS 3.0 支援将多个小档案合并储存到一个较大档案中,目前开发进展比较顺利,预计 5 月份可以释出 3.0 版本。
提升磁碟 IO 的另外一个技巧,一次尽可能多写入或多读取。也就是说,将程式的读写 buffer 设定得尽可能大一些。例如日志或者 redo log 的写入,不是每次呼叫都直接写磁碟,而是先 WordPress 加速缓存到内存中,等 buffer 满了再写入磁碟,也可以定时写入磁碟。
操作系统和 C 库函式通常会对写入的档案内容做 WordPress 加速缓存,以减少实际写档案的次数。直接呼叫系统函式 fsync 或 C 函式 fflush 将使系统的 WordPress 加速缓存机制失效,此时将强制把内容刷到磁碟上。除非必需,否则不要执行强制刷盘操作。
注:如果没有特别说明,文中说的磁碟指的是硬碟。