我们在做块设备调优的时候, 我们关心的是块设备是如何被访问的,也就是访问模式(比如说每次从什么地方读,每次读多少块,热点在哪里等),至于每次读写的什么数据我们并不关心. 这些模式当然可以自己去构造,但是如果能把真实应用的访问模式记录下来,并且在调优的时候能重放,我们就可以一遍又一遍的调试直到达到最佳的性能.

这个事情听起来貌似很麻烦,对吧? 幸运的是fio配合blktrace可以作这样的事情. 流程是blktrace负责录制真实应用对设备的访问模式, fio负责读入这些模式, 同时重放模拟对设备的访问.

背景资料:

blktrace使用可以参看这里

fio使用可以参看这里

在做演示前需要强调的是: 对设备的读写是模拟它的模式, 所以会破坏原来的数据,请谨慎, 我也是用虚拟的设备作演示的:

我们要演示的设备是 /dev/ram0, 设备大小128M:

$ uname -r

2.6.35-22-generic

$ cat /etc/lsb-release

DISTRIB_ID=Ubuntu

DISTRIB_RELEASE=10.10

DISTRIB_CODENAME=maverick

DISTRIB_DESCRIPTION="Ubuntu 10.10"

$ sudo blockdev --getsize /dev/ram0

131072

在终端#1里面运行blktrace捕获设备的访问模式:

$ sudo blktrace /dev/ram0

在终端#2里面运行应用程序,这里只是简单的运行下dd在设备上写入64K数据:

$ sudo sudo dd if=/dev/zero of=/dev/ram0 count=16 bs=4096 oflag=direct

记录了16+0 的读入

记录了16+0 的写出

65536字节(66 kB)已复制,9.219e-05 秒,711 MB/秒

回到终端#1:

按下CTRL+C终止blktrace的运行, 可以看到该设备的录制文件有了.

$ ls ram0.blktrace.*

ram0.blktrace.0 ram0.blktrace.1

#转化成二进制文件格式

$ blkparse ram0 -d dd.bin >/dev/null

#重放日志:

$ sudo fio --name=replay --filename=/dev/ram0 --thread --direct=1 --read_iolog=dd.bin

replay: (g=0): rw=read, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1

fio 1.50.2

Starting 1 thread

got timestamp notify: 4000001, 0

replay: (groupid=0, jobs=1): err= 0: pid=31484

read : io=102400 B, bw=50000KB/s, iops=12500 , runt= 2msec

clat (usec): min=6 , max=13 , avg= 6.56, stdev= 1.42

lat (usec): min=7 , max=15 , avg= 7.84, stdev= 1.60

write: io=65536 B, bw=32000KB/s, iops=8000 , runt= 2msec

clat (usec): min=9 , max=39 , avg=11.88, stdev= 7.33

lat (usec): min=10 , max=41 , avg=13.06, stdev= 7.53

cpu : usr=0.00%, sys=1000.00%, ctx=1, majf=0, minf=5

IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%

submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%

complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%

issued r/w/d: total=25/16/0, short=0/0/0

lat (usec): 10=68.29%, 20=29.27%, 50=2.44%

Run status group 0 (all jobs):

READ: io=100KB, aggrb=50000KB/s, minb=51200KB/s, maxb=51200KB/s, mint=2msec, maxt=2msec

WRITE: io=64KB, aggrb=32000KB/s, minb=32768KB/s, maxb=32768KB/s, mint=2msec, maxt=2msec

Disk stats (read/write):

ram0: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=-nan%

如果我们用strace来跟踪会看到以下的系统调用, 确认我们的重放是成功的:

31350 open(“/dev/ram0”, O_RDWR|O_DIRECT|O_NOATIME) = 8

31350 ioctl(8, BLKFLSBUF, 0xffffffffffffffff) = 0

31350 fadvise64(8, 0, 0, POSIX_FADV_SEQUENTIAL) = 0

31350 lseek(8, 0, SEEK_SET) = 0

31350 write(8, “\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0″…, 4096) = 4096

31350 write(8, “\30\260!\6\233\221\264\210\0036i\325\260u\331\17\300\306A)\324\307\221\17\3308\220\v\264\247\363\35″…, 4096) = 4096

总结: 该模拟破坏数据有风险, 但是省去了构造应用环境的时间,在调优的时候很有帮助.

玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐