备注:
使用的是yum 进行的安装,大家可以使用源码编译安装(centos 7)
安装
yum install -y fio
使用
filename: 指定文件(设备)的名称。可以通过冒号分割同时指定多个文件,如filename=/dev/sda:/dev/sdb。
directory: 设置filename的路径前缀。在后面的基准测试中,采用这种方式来指定设备。
name: 指定job的名字,在命令行中表示新启动一个job。
direct: bool类型,如果设置成true (1),表示不使用io buffer。
ioengine: I/O引擎,现在fio支持19种ioengine。默认值是sync同步阻塞I/O,libaio是Linux的native异步I/O。关于同渣耐脊步异步,阻塞和非阻塞模型可以参考文章“使用异步 I/O 大大提高应用程序的性能”。
iodepth: 如果ioengine采用异步方式,该参数表示一批提交保持的io单元数。该参数可参考文章“Fio压测工亩滚具和io队列深度理解和误区”。
rw: I/O模式,随机读写,顺序读写等等。
bs: I/O block大小,默认是4k。
size: 指定job处理的文件的大小。
numjobs: 指定job的克隆数(线程)。
time_based: 如果在runtime指定的时间还没到时文件就被读写完成,将继续重复知道runtime时间结束。
runtime: 指定在多少秒后停止进程。如果未指定该参数,fio将执行至指定的文件读写完全完成。
group_reporting: 当同时指定了numjobs了时,输出结果按组显示。
参考说明
filename=/dev/sdb1 #测试文件名称,通常选择需要测试的盘的data目录
direct=1 #测试过程绕过机器自带的buffer。使测试结果更真实
rw=randwrite #测试随机写的I/O
rw=randrw #测试随机写和读的I/O
bs=16k #单次io的块文件大小为16k
bsrange=512-2048 #同上,提定数据块的大小范围
size=5G #本次的测试文件大小为5g,以每次4k的io进行测试
numjobs=30 #本次的测试线程为30个
runtime=1000 #测试时间1000秒,如果不写则一直将5g文件分4k每次写完为止
ioengine=psync #io引擎使用psync方式
rwmixwrite=30 #在混合读写的模式下,写占30%
group_reporting #关于显示结果的,汇总每个进程的信息
lockmem=1G #只使用1g内存进行测试
zero_buffers #用0初始化系统buffer
nrfiles=8 #每个进程生成文如渗件的数量
#顺序读
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
#顺序写
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
#随机读
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
#随机写
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
#混合随机读写
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop
#复制下面的配置内容,将directory=/path/to/test修改为你测试硬盘挂载目录的地址,并另存为fio.conf
[global]
ioengine=libaio
direct=1
thread=1
norandommap=1
randrepeat=0
runtime=60
ramp_time=6
size=1g
directory=/path/to/test
[read4k-rand]
stonewall
group_reporting
bs=4k
rw=randread
numjobs=8
iodepth=32
[read64k-seq]
stonewall
group_reporting
bs=64k
rw=read
numjobs=4
iodepth=8
[write4k-rand]
stonewall
group_reporting
bs=4k
rw=randwrite
numjobs=2
iodepth=4
[write64k-seq]
stonewall
group_reporting
bs=64k
rw=write
numjobs=2
iodepth=4
#测试
fio fio.conf
打反了吧,是 ifo文件吧?【IFO—DVD文件】
IFO文件的全称是InFOrmation。IFO文件为播放器提供十分重要的导航信息。比如一个章节从什么地方开始,一个特定的音频流或者字幕流在什么地方,等等。因此IFO文件是控制DVD播放进程的重要文件。
【IFO文件作用】
DVD光盘上的目录包含了AUDIO_TS和VIDEO_TS 两个子目录。由于Audio_ts是保留给DVD版的激光唱片DVD-AUDIO使用的,所以在DVD影片光唤神首盘中,这个文件夹是空的;而Video_ts中则保存着影片所有的视频音频和字幕信息。依照DVD影片光盘(DVD-VIDEO)标准的规定,一个标准的Video_ts文件夹中应该包含三种类型的文件:VOB、IFO、BUP,下面我们再来分别看一下它们各自的作用。
VOB (Video OBjects视频目标文件):VOB文件用来保存DVD影片中的视频数据流、音频数据流、多语言字幕数据流以及供瞎拍菜单和按钮使用的画面数据。由于一个VOB文件中最多可以保存1个视频数据流、9个音频数据流和32个字幕数据流,所以DVD影片也就可以拥有最多9种语言的伴音和32种语言的字幕。
IFO (InFOrmation信息文件):IFO文件用来控制VOB文件的播放。文件中保存有怎样以及何时播放VOB文件中数据的控制信息,比如段落的起始时间、音频数据流的位置、字幕数据流的位置等信息。DVD机或者播放软件通过读取IFO文件,才能把组成DVD影片的各种数据有机地结合起来进行播放。由于IFO文件关系到光盘能否正常播放,因此所有的IFO文件都有一个备份——即相应同名的BUP文件。标准的DVD光盘都是自动播放的。是否自动播放,在于微机播放器的设置。
BUP (BackUP备份文件):BUP文件和IFO文件的内容完全相同,是IFO文件的备份。由于IFO文件对于保证影片的正常播放非常和数重要,所以需要保留一个副本,以备在IFO文件的读取发生错误时仍然可以通过读取BUP文件来得到相应的信息。
MySQL 里经常说到的 WAL技术,也就是先写日志,再写磁盘。
当内存数据页跟磁盘数据页内容不一致的时冲坦候,我们成这个内存页为“脏页”。内存数据写入磁盘后,内存和磁盘上的数据页内容就一致了,称为“干净页”。
MySQL 从 内存更新到磁盘的过程,称为刷脏页的过程(flush)。
InnoDB 刷脏页的时机:
往前推进之后,就要把两个点之间的日志对应的所有脏页都 flush 到磁盘上。
这种情况是 InnoDB 要尽量避免的。因为出现这种情况,整个系统都不能接受更新。更新数会跌为0。
那么为什么不能直接淘汰所有的内存,下次请求的时候,再从磁盘读入数据页,然后 拿 redo log 出来应用?这其实也是从性能的角度来考虑的,刷脏页一定写盘,就保证了每个数据页只有两种情况:
这种情况在日常应用中其实是常态。 在InnoDB 中,使用缓冲池 (buffer pool)管理内存,缓冲池中的内存页有三种状态:
刷脏页是常态,所以如果出现以下的情况,都会明明显影响性能:
首先,需要让 InnoDB 正确指导系统的 IO 能力,来控制刷脏页的快慢。
innodb_io_capacity 这个参数,它会告诉 InnoDB 你的磁盘能力,所以尽量设置成磁盘的 IOPS。可以使用 fio 工具来获取。
然后,如果你来设计策略控制刷脏页的速度,会参考哪些因素呢?
这个问题可以这么想,如果刷太慢,会出现什么情况?首先是内存脏页太多,其次是 redo log 写满。
所以,InnoDB 的刷盘速度就是要参考这两个因素:一个是脏页比例,一个是 redo log 写盘速度。
参数 innodb_max_dirty_pages_pct 是脏页比例上限,默哗凯认是 75%。InnoDB 会根据当前的脏页比例,计算出一个数字 F1。
InnoDB 写入日志都会有一个序号,当前写入序号跟 checkpoint 对应的序号之间的差值,假设为N。InnoDB 会根据N 计算出 F2.
根据 F1和散芦桐F2 取其中较大的值为 R,之后引擎就可以按照 Innodb_io_capacity 定义的能力乘以 R% 来控制刷脏页的速度。
MySQL 中有一个机制,刷脏页的时候如果数据页旁边的数据页也是脏页,那么就会一起刷掉,而且这个逻辑是可以蔓延的,所以对于每个相邻的数据页,都会被一起刷。
在 InnoDB 中,innodb_flush_neighbors 参数就是用来控制这个行为的,值为 1 的时候会有上述的“连坐”机制,值为 0 时表示不找邻居,自己刷自己的。
在使用机械硬盘时,这个优化很有意义,可以减少很多随机 IO。如果使用的是 SSD 这种IOPS 比较高的设备,可以设置innodb_flush_neighbors 为0,只刷自己,这个时候 IOPS 往往就不是性能瓶颈了。只刷自己就可以提高刷脏页的速度,减少 SQL 语句的响应时间。
binlog 的写入机制比较简单:事务执行的过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到binlog 文件中。
系统给 binlog cache 分配了一片内存,每个线程一个,参数 binglog_cache_size 用于控制单个线程内 binlog cache 的内存大小,超过就要暂存在磁盘。
事务提交的时候,执行器把 binlog cache 里完整事务写入到 binlog 中,并清空 binlog cache。
write 和 fsync 的时机,是由参数 sync_binlog 控制的:
因此,在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成 0,比较常见的是将其设置为 100~1000 中的某个数值。但是,将 sync_binlog 设置为 N,对应的风险是:如果主机发生异常重启,会丢失最近 N 个事务的 binlog 日志。
事务的执行过程中,生成的 redo log 是要先写到 redo log buffer 的。
redo log 三种状态:
日志写到 redo log buffer 是很快的,write 到 page cache 也差不多,但是持久化到磁盘的速度就慢多了。
InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,取值如下:
InnoDB 有一个后台线程,每隔 1 秒,就会把 redo log buffer 中的日志,调用 write 写到文件系统的 page cache,然后调用 fsync 持久化到磁盘。
组提交 机制
日志逻辑序列号(log sequence number,LSN)是一个单调递增的值,对应 redo log 的一个个写入点。每次写入的长度为 lenght 的 redo log,LSN的值就会加上 length。
LSN 也会写到 InnoDB 的数据页中,来确保数据也不会被多次执行重复的 redo log。
在一组提交里面,组员越多,节约磁盘 IOPS 的效果越好。在并发更新的场景下,第一个事务写完 redo log buffer 以后,接下来这个 fsync 越晚调用,组员可能越多,节约 IOPS 的效果就越好。
WAL机制主要得益于两个方面:
如果你的 MySQL 现在出现了性能瓶颈,而且瓶颈在 IO 上,可以通过哪些方法来提升性能呢?
针对这个问题,可以考虑以下三种方法:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)