了解你的磁盘之使用bonnie++测试磁盘性能

来源:互联网 发布:神速百度快速排名优化 编辑:程序博客网 时间:2024/06/13 13:48

了解你的磁盘之使用bonnie++测试磁盘性能 


上一篇博文介绍了如何获取磁盘的基本参数 磁盘序列号,转速,通电时间,温度等等,其实我们更关心的是性能,读写性能。很多开源工具都能测试磁盘性能,iozone,bonnie,bonnie++,fio等等,都是不错的工具,本文介绍bonnie++。

   bonnie++,顾名思义也得知道有bonnie的存在。bonnie这个程序存在一些问题,比如对超过2G大小的文件不支持,所以Russel Coker大神写了bonnie++,bonnie++算是一个比较知名的的benchmark测试工具,可以用来测试硬盘以及文件系统的性能。想去下载源码的可以到http://www.coker.com.au/bonnie++/,想去瞻仰一下Coker大神的,http://www.coker.com.au/russell/这是他的网站,大神写的一手好博客,被我果断收藏了。
   首先是下载及安装,目前最新的版本是1.03e:
  1.     wget http://www.coker.com.au/bonnie++/bonnie++-1.03e.tgz
    安装无甚好讲,直接解压,configure,make ,make install即可。
   
   这些选项当中 
   -f 表示fast mode,快速模式,因为bonnie++写有putc的测试,读有getc的测试,不用block,每次读或者写一个字节的测试,如果加了-f这个option,这个字节的测试就跳过了。
   -D open的时候,带上O_DIRECT标志,对应的代码逻辑在bon_io.cpp
  1.     flags = O_RDWR | O_CREAT | O_EXCL;
  2.     if(m_use_direct_io)
  3.     {
  4.           flags |= O_DIRECT;
  5.     }
   -b 写完之后,会调用fsync,刷到磁盘。
   -s 是用来制定测试用的文件的大小,如果你没有加 -s这个option,系统会默认使用2倍内存大小的文件,比如我的内存是2G,那么bonnie会使用4G的文件来测试性能,原因在于减少缓存的影响。对Linux下文件和page cache感兴趣的筒子可以看我的这篇博文:file和page cache的一些事儿 。代码逻辑在bonnie++.cpp
  1.   if(globals.ram && !setSize)
  2.   {
  3.     if(file_size < (globals.ram * 2))
  4.       file_size = globals.ram * 2;
  5.     // round up to the nearest gig
  6.     if(file_size % 1024 > 512)
  7.       file_size = file_size + 1024 - (file_size % 1024);
  8.   }
    如果用户-s选项,又当如何?
    常用的指定-s选项的是这样的:
  1.     bonnie++ -d /home/disk_test/ -s 16000:1048576 -r 1024 -u root
    -s 16000:1048576的含义是用16000MB的文件来做实验,chunksize是1048576B,注意冒号前半部分的单位是MB,后半部分的单位是B。当然了-s16G:1048576也是合法的参数。代码逻辑在bonnie++.cpp :    
  1.      case 's':
  2.             {
  3.               char *sbuf = strdup(optarg);
  4.               char *size = strtok(sbuf, ":");
  5.               file_size = atoi(size);
  6.               char c = size[strlen(size) - 1];
  7.               if(== 'g' || c == 'G')
  8.                 file_size *= 1024;
  9.               size = strtok(NULL, "");
  10.               if(size)
  11.               {
  12.                 int tmp = atoi(size);
  13.                 c = size[strlen(size) - 1];
  14.                 if(== 'k' || c == 'K')
  15.                   tmp *= 1024;
  16.                 globals.set_chunk_size(tmp);
  17.               }
  18.               setSize = true;
  19.             }
  20.             break;
    注意chunksize也好,filesize也好,都是有限制的。先说chunksize最小是256B,最大是1MB,而且必须是256,512,1024,2048这种256×2^n的值,否则也报错。至于filesize,要大于2倍的内存值。下面二个误用,第一个是因为file_size小于2倍内存,bonnie十分kind的提醒内存大小是1936M,第二个原因是非256的2的幂次倍。
   
    如果filesize超过1G,会存储到多个文件,最大filesize不能超过1000G. 
  1.     #define MaxIOFiles 1000
        #define IOFileSize 1024

  2.     m_chunks_per_file(Unit / m_chunk_size * IOFileSize)
  3.     ....
      if(file_size > IOFileSize * MaxIOFiles)
        usage();
    其他的就没啥好说的了,直接开始测试吧,我比较懒,直接用了默认选项:   
  1.     bonnie++ -u manu
    输出是这样子的:
  1. Version 1.03e ------Sequential Output------ --Sequential Input- --Random-
  2.                     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
  3. Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
  4. manu 4G 33516 92 70332 11 23182 6 35877 83 83433 10 127.8 0
  5.                     ------Sequential Create------ --------Random Create--------
  6.                     -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
  7.               files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
  8.                  16 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
  9. manu,4G,33516,92,70332,11,23182,6,35877,83,83433,10,127.8,0,16,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++
    有一陀++,表示测试结果没有出来,作者采取了审慎的态度,他认为不准确的数据宁愿用++,也不愿意show出来,作者在bonnie++.8中有如下的说明:对作者认真负责的态度赞一个。
  1. For every test two numbers are reported, the amount of work done (higher numbers are better) and the percentage of CPU time taken to perform the work (lower numbers are better). If a test completes in less than 500ms then the output will be displayed as "++++". This is because such a testresult can't be calculated accurately due to rounding errors and I would rather display no result than a wrong result.
    对这个问题耿耿于怀的筒子,可以看下How To Get Rid Of The Plus Signs In Bonnie++ Output,作者提供了解决之道,就是使用更大一点的 -n选项,-n选项的意思是做create文件实验的时候,创建多少个文件,默认是16×1024个,如果把这个值放大成128×1024,我们就有更大的机会获取准确值:即采用 -n 128参数。这个我没有试过,感兴趣的筒子去阅读并实验可也。
    OK,这个++解释完了,我们继续。这个输出也太丑了,完全没有考虑到人的感受啊,幸好提供了bon_csv2html工具:
  1. echo manu,4G,33516,92,70332,11,23182,6,35877,83,83433,10,127.8,0,16,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++ |bon_csv2html >>bon_result.htm
    将输出的最后一行,调用bon_csv2html,就得到了html文件:如下所示:

   我的磁盘的性能就测试出来了:
   Sequential Output下的 Per Char是值用putc方式写,毫无疑问,因为cache的line总是大于1字节的,所以不停的骚扰CPU执行putc,看到cpu使用率是92%.写的速度是33MB/s,还不错。
   Sequential Output是按照block去写的,明显CPU使用率就下来了,速度也上去了,越是70MB/s。
   Sequential Input下的Per Char是指用getc的方式读文件,速度是35.8MB/s,CPU使用率是83%。
   Sequential Input下的block是指按照block去读文件,速度是83MB/s,CPU使用率是10%。
   另一个比较有意思的Random Seeks,含义是随机寻址。但是实际上,不仅是seek,还包括100%的读和10%的写, 这项性能指标是127.8次/s。对应如下代码 
  1. #define UpdateSeek (10)

  2.   if(rc == 1 && ticket) do
  3.   {
  4.     bool update;
  5.     if( (lseek_count++ % UpdateSeek) == 0)
  6.       update = true;
  7.     else
  8.       update = false;
  9.     if(file->doseek(rand() % num_chunks, update) )
  10.       exit(1);
  11.   }
  12.    ....
  13. int
  14. CFileOp::doseek(long where, bool update)
  15. {
  16.   if (seek(where, SEEK_SET) == -1)      // 100%的seek
  17.     return io_error("lseek in doseek");
  18.   if (read_block(PVOID(m_buf)) == -1)  //100%的读

  1.     return io_error("read in doseek");

  2.   /* every so often, update a block */
  3.   if (update)                         //10%的写
  4.   { /* update this block */

  5.     /* touch a byte */
  6.     m_buf[int(rand()) % m_chunk_size]--;
  7.     if(seek(where, SEEK_SET) == -1)
  8.       return io_error("lseek in doseek update");
  9.     if (write_block(PVOID(m_buf)) == -1)
  10.       return io_error("write in doseek");
  11.     if(m_sync)
  12.     {
  13.       if(fsync(m_fd[m_file_ind]))
  14.       {
  15.         fprintf(stderr, "Can't sync file.n");
  16.         return -1;
  17.       }
  18.     }
  19.   } /* update this block */
  20.   return 0;
  21. }
    另外,bonnie++提供了zcav工具,至于zcav的详细原理我还知之不深,我要陪老婆了,今天还没散步。总之了,我照葫芦画瓢招 也得到了数据:原理部分希望以后补充,和Coker还有其他大神的得到的图片是相似的。原谅我没搞懂就show 图片出来,谁让我是个虚荣的人呢,阿弥托佛,善勒个哉的。
  1. zcav -f /dev/sda
    然后用gnuplot绘制的图片,大爱这张图片:
   
参考文献:
1 GPFS performace report (uses bonnie++ command) 
2 How To Get Rid Of The Plus Signs In Bonnie++ Output
使用Bonnie++进行系统IO性能测试
0 0
原创粉丝点击