2019独角兽企业重金招聘Python工程师标准>>>
IO调优(硬盘的读写)
IO算法:默认为cfq(完全公平算法)
- 1. 影响磁盘io的物理因素:
- 2. 通过队列技术,调整IO的调度算法:
-----------------------------------------------------
影响磁盘io的物理因素:
磁盘:
-1. 存储的密度 磁盘的外圈存储的数据量大
-2. 磁盘的转速
-3 .通常分区号越低越靠近磁盘的外圈(将常用的分区尽量放到外圈)
先介绍一个清空缓存的命令
[root@Salt-master ~]# sysctl -w vm.drop_caches=3 # 清空缓存
[root@Salt-master ~]# echo 3 > /proc/sys/vm/drop_caches # 清空和缓存
----------------------参数的调整-------------------------
安装kernel-doc (可以不安装,这个是kernel的文档)
yum -y install kernel-doc
文档的目录:[root@localhost Documentation]# pwd
/usr/share/doc/kernel-doc-3.10.0/Documentation
所有的调优只会对当前生效,重启系统后就失效了,所以,需要将调优的策略放入到开机脚本中/etc/rc.local
1.查看磁盘IO的调度算法:
[root@localhost queue]# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq # []中的值为当前值
2. 默认情况下kernel会自动的优化所有的读访问:
默认设置为[root@localhost queue]# blockdev --getra /dev/sda
8192
的值的一半
[root@localhost queue]# cat /sys/block/sda/queue/read_ahead_kb # 查看预先读取的量centos 7 默认为4096,centos6默认值为128
4096
当请求来的时候,kernel会先读取上面的默认值请求,然后再处理写请求
# 调整磁盘预读取参数的命令:(无论何种调度算法这两个参数都是可以调节的)
- read_ahead_kb (单位是K,预读记忆)
- 1 : [root@localhost queue]# echo 8192 > /sys/block/sda/queue/read_ahead_kb
[root@localhost queue]# blockdev --getra /dev/sda
16384
- 2 : [root@localhost queue]# blockdev --setra 8192 /dev/sda
[root@localhost queue]# cat /sys/block/sda/queue/read_ahead_kb
4096
两种方法都可以,但是记住blockdev --getra /dev/sda 是/sys/block/sda/queue/read_ahead_kb的倍数关系,设置其中一个,另外一个自动就会发生变化
# 参数的影响: 当预读取这个值设置的特别大的时候,会影响写操作;当请求的数据比较少的时候,等待的时间会比较长
使其他的操作会更慢(适合读请求比较大的服务可以对该参数进行设定)
3. 调整disk 队列:
- nr_requests # 请求队列的长度。默认可以接受128个请求
/sys/block/sda/queue/nr_requests
[root@Salt-master ~]# cat /sys/block/sda/queue/nr_requests
128
# 队列长的话,可以提升硬盘的吞吐量,但是占用内存也越多 centos6 和 7 的默认值都是128 (如果用作文件服务器或者内存比较大可以适当的进行调整)
4. 调整调度算法:
centos6:
在企业版6中有4中调度算法:
[root@Salt-master ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]
centos7:
在企业版7中只有3种调度算法:
[root@localhost ~]# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
修改调度算法:
[root@localhost iosched]# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
[root@localhost iosched]# echo cfq > /sys/block/sda/queue/scheduler # 修改IO调度算法
[root@localhost iosched]# cat /sys/block/sda/queue/scheduler
noop deadline [cfq]
当修改io算法后,我们在来查看一下iosched,发现已经发生了变化
[root@localhost iosched]# ll /sys/block/sda/queue/iosched
total 0
-rw-r--r--. 1 root root 4096 Jan 13 21:50 back_seek_max
-rw-r--r--. 1 root root 4096 Jan 13 21:50 back_seek_penalty
-rw-r--r--. 1 root root 4096 Jan 13 21:50 fifo_expire_async
-rw-r--r--. 1 root root 4096 Jan 13 21:50 fifo_expire_sync
-rw-r--r--. 1 root root 4096 Jan 13 21:50 group_idle
-rw-r--r--. 1 root root 4096 Jan 13 21:50 low_latency
-rw-r--r--. 1 root root 4096 Jan 13 21:50 quantum
-rw-r--r--. 1 root root 4096 Jan 13 21:50 slice_async
-rw-r--r--. 1 root root 4096 Jan 13 21:50 slice_async_rq
-rw-r--r--. 1 root root 4096 Jan 13 21:50 slice_idle
-rw-r--r--. 1 root root 4096 Jan 13 21:50 slice_sync
-rw-r--r--. 1 root root 4096 Jan 13 21:50 target_latency
备注:当修改调度算法的时候,iosched(里面是真正要调节的参数)也随之发生了变化
算法解释:
centos6中的IO调度算法有4种,centos7中没有anticipatory算法:
- 1. cfq:默认 电梯算法:完全公平队列(适合各种负载,多进程的读读写写)
[root@Salt-master queue]# echo cfq > /sys/block/sda/queue/scheduler
[root@Salt-master queue]# cat scheduler
noop anticipatory deadline [cfq]
[root@Salt-master queue]# cd iosched/
[root@Salt-master iosched]# ls
back_seek_max fifo_expire_async group_idle low_latency slice_async slice_idle
back_seek_penalty fifo_expire_sync group_isolation quantum slice_async_rq slice_sync
关键参数:
queued: 一个周期内最大的请求数
quantum: 默认的请求队列是8个请求
cfq的细化操作
cfq分为3类:()优先级队列
1.real-time(实时的)优先级0~7
2.best-effort(以最好的效果大家都可以访问的意思轮询)优先级0~7(默认值是轮询)
3.idle(空闲的时候在使用)
针对 cfq 可以使用ionice 命令 用来在执行命令或者制定某一个PID使用那个类的cfq算法(更改分类即优先级):
例子:ionice -n0 -c1 -p pid (最高优先级)
ionice -n7 -c2 cmd
ionice -c3 cmd
其中 -n代表优先级,数字越小,优先级就越高(在类1和类2中有);-c 代表使用哪一个类
# 在使用class 1 的时候,有可能会出现系统假死的现象,因为它有可能会出现独占的情况。慎用
# 只能在cfq中使用
- 2. deadline(最后期限):行为是可以预知的(5毫秒)适合实时系统(适合做有虚拟机的物理主机时使用,处理小数据的写入)
当调度算法为deadline时,可以调节的参数有:read_expire 和 write_expire
[root@localhost ~]# cd /sys/block/sda/queue/iosched/ # 进入调整目录
[root@localhost iosched]# ls
fifo_batch front_merges read_expire write_expire writes_starved
关键参数:
read_expire :读过期时间 默认值500(单位是毫秒)
write_expire:写过期时间 默认值5000
front_merges: 写请求合并开关默认值为1,开起的状态(在当前的写请求没有结束的时候,新的写请求与当前的写请求有关联的时候,就继续写请求)
# 在上述时间周期到期之前系统一定会提供需要的读和写服务。目标:优化等待时间
- 3. anticipatory:(猜想算法)(centos7中没有该算法)在读操作结束后,会稍等一下,看看是否还有临近的读(写)操作,适合于大量的顺序读(写)操作业务(大文件读写操作,web服务)
[root@Salt-master queue]# echo anticipatory > scheduler
[root@Salt-master iosched]# cd /sys/block/sda/queue/iosched/
[root@Salt-master iosched]# ls
antic_expire est_time read_batch_expire read_expire write_batch_expire write_expire
关键参数:
antic_expire:默认值为6秒 ,当完成请求会等6秒,看看有没有临近的操作
read_expire: 默认值为125毫秒
write_expire:默认值为250毫秒
目标:优化读请求,提高完成率。
- 4. noop:什么都没有:优势就是cpu会很轻松,适用于ssd硬盘和虚拟机使用:
没有任何调节参数
[root@Salt-master queue]# echo noop > scheduler