现在的位置: 首页 > 综合 > 正文

磁盘io的一些知识和总结

2014年10月27日 ⁄ 综合 ⁄ 共 2602字 ⁄ 字号 评论关闭

读/写IO,最为常见说法,读IO,就是发指令,从磁盘读取某段扇区的内容。指令一般是通知磁盘开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读,还是写。磁盘收到这条指令,就会按照指令的要求,读或者写数据。控制器发出的这种指令+数据,就是一次IO,读或者写。

大/小块IO,指控制器的指令中给出的连续读取扇区数目的多少,如果数目很大,比如128,64等等,就应该算是大块IO,如果很小,比如1, 4,8等等,就应该算是小块IO,大块和小块之间,没有明确的界限。

连续/随机IO,连续和随机,是指本次IO给出的初始扇区地址,和上一次IO的结束扇区地址,是不是完全连续的,或者相隔不多的,如果是,则本次IO应该算是一个连续IO,如果相差太大,则算一次随机IO。连续IO,因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或换道时间极短;如果相差太大,则磁头需要很长的换道时间,如果随机IO很多,导致磁头不停换道,效率大大降底。

顺序/并发IO,这个的意思是,磁盘控制器每一次对磁盘组发出的指令套(指完成一个事物所需要的指令或者数据),是一条还是多条。如果是一条,则控制器缓存中的IO队列,只能一个一个的来,此时是顺序IO;如果控制器可以同时对磁盘组中的多块磁盘,同时发出指令套,则每次就可以执行多个IO,此时就是并发IO模式。并发IO模式提高了效率和速度。

IO并发几率。单盘,IO并发几率为0,因为一块磁盘同时只可以进行一次IO。对于raid0,2块盘情况下,条带深度比较大的时候(条带太小不能并发IO,下面会讲到),并发2个IO的几率为1/2。其他情况请自行运算。

IOPS( (Input/Output Operations Per Second))。一个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的因素,只有一个,就是寻道时间。

寻道时间指的是硬盘的平均寻道时间(Average Seek Time),是指硬盘在接收到系统指令后,磁头从开始移动到移动到数据所在磁道所需要的平均时间,单位为毫秒(ms)。这是衡量硬盘的一个重要参数,其数值越小,则性能越好。现在主流的硬盘的寻道时间都在10ms左右或以下。

从原理上解释上面的表象,一般来说,硬盘读取数据的过程是这样的,首先是将磁头移动到磁盘上数据所在的区域,然后才能进行读取工作。磁头移动的过程又可以 分解为两个步骤,其一是移动磁头到指定的磁道,也就是寻道,这是一个在磁盘盘片径向上移动的步骤,花费的时间被称为“寻道时间”;其二就是旋转盘片到相应 扇区,花费的时间被称为“潜伏时间”(也被称为延迟)。那么也就是说在硬盘上读取数据之前,做准备工作上需要花的时间主要就是“寻道时间”和“潜伏时间”
的总和。真正的数据读取时间,是由读取数据大小和磁盘密度、磁盘转速决定的固定值,
在应用层没有办法改变,但应用层缺可以通过改变对磁盘的访问模式来减少“寻道时间”和“潜伏时间”, 我们上面提到的在应用层使用cache然后排序的方式,无疑就是缩短了磁盘的寻址时间。由于磁头是物理设备,也很容易理解,为什么中间插入对其他小文件的读写会导致速度变慢很多。


目前磁盘都是机械方式运作的,主要体现在磁盘读写前寻找磁道的过程。磁盘自带的读写缓存大小,对于磁盘读写速度至关重要。读写速度快的磁盘,通常都带有较大的读写缓存。磁盘的寻道过程是机械方式,决定了其随机读写速度将明显低于顺序读写。在我们做系统设计和实现时,需要考虑到磁盘的这一特性。

目前磁盘顺序读取的速度并不差,比如普通硬盘的IO可以达到每秒40~60MB,好一些的硬盘可以达到每秒100MB左右。在多进程或多线程并发读取磁盘的情况下,随着并发数的增加,磁盘IO效率将大大下降。主要是因为每次读写,磁道可能存在较大的偏移,磁道寻址时间加大,导致磁盘IO性能急剧下降。对于这种场景,优化方案是尽可能减少并发读写的进程数或线程数。可以用锁的机制,也可以采用专门的磁盘IO线程来对磁盘进行读写。

    文件数多了之后,比如达到上千万个文件,当随机访问众多文件时,文件系统的性能会急剧下降。业界流行的做法是将多个小文件合并存储到一个大文件中的方式来降低文件数。

提升磁盘IO的另外一个技巧,一次尽可能多写入或多读取。也就是说,将程序的读写buffer设置得尽可能大一些。例如日志或者redo log的写入,不是每次调用都直接写磁盘,而是先缓存到内存中,等buffer满了再写入磁盘,也可以定时写入磁盘。


2. 多线程随机读、处理速度、响应时间

多线程随机读的处理速度可以达到单线程随机读的10倍以上,但同上也带来了响应时间的增大。测试结论如下:(每个线程尽量读)

结论标明增加线程数,可以有效的提升程序整体的io处理速度。但同时,也使得每个io请求的响应时间上升很多

从底层的实现上解释这个现象:应用层的io请求在内核态会加入到io请求队列里面。内核在处理io请求的时候,并不是简单的先到先处理,而是根据磁盘的特 性,使用某种电梯算法,在处理完一个io请求后,会优先处理最临近的io请求。这样可以有效的减少磁盘的寻道时间,从而提升了系统整体的io处理速度。但对于每一个io请求来看,由于可能需要在队列里面等待,所以响应时间会有所提升。

响应时间上升,应该主要是由于我们测试的时候采用每个线程都尽量读的方式。在实际的应用中,我们的程序都没有达到这种压力。所以,在io成为瓶颈的程序里面,应该尽量使用多线程并行处理不同的请求。对于线程数的选择,还需要通过性能测试来衡量。

抱歉!评论已关闭.