Journaling

非日志型文件系统

在非日志型文件系统中,对文件系统实施一个写操作,内核会首先修改对应的元数据,然后修改数据块。如果在写入元数据时,文件系统发生崩溃或某种故障,那么数据的一致性将会遭到破坏。fsck
命令可以在下次重启时检查所有的元数据并修复数据一致性,但是如果文件系统非常大,或者系统运行关键业务不允许停机,使用非日志型文件系统的风险会非常高。

日志型文件系统

日志型文件系统的区别在于,在进行对文件系统写数据之前,写将数据写到「日志区」,然后再写入文件系统,在写入文件系统之后删除日志。日志区可以在文件系统内部也可以在文件系统外部。日志区的数据称作文件系统日志,这些数据包含了修改了的元数据,也可能包含将要修改的数据。写日志也会带来一定的额外开销。

针对固态硬盘优化

  1. 关闭日志功能
    fstab里加挂载参数data=writeback
  2. 启用 TRIM 功能
    Linux内核从2.6.33开始提供TRIM支持,所以先运行“uname
    -a”命令,查看自己的内核版本,如果内核版本低于2.6.33的,请先升级内核。
    然后运行“hdparm -I
    /dev/sda”查看自己的硬盘支不支持TRIM技术,如果支持,你会看到
    Data Set Management TRIM supported
    如果上面两个条件都满足了,就可以在fstab中添加discard来开启TRIM功能,如:
    原始的UUID=2f6be0cf-2f54-4646-b8c6-5fb0aa01ef23 / ext4
    defaults,errors=remount-ro 0 1
    改后的UUID=2f6be0cf-2f54-4646-b8c6-5fb0aa01ef23 / ext4
    discard,defaults,errors=remount-ro 0 1

图3 CFQ的工作流程

IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调度器也被叫做电梯
(elevator)而相应的算法也就被叫做电梯算法,而Linux中IO调度的电梯算法有好几种,一个叫做as(Anticipatory),一个叫做cfq(Complete
Fairness Queueing),一个叫做deadline,还有一个叫做noop(No
Operation),具体使用哪种算法我们可以在启动的时候通过内核参数elevator来指定。

/etc/sysctl.conf

iozone

使用iozone对文件系统进行基准测试

  • $ iozone -a
    iozone将在所有模式下进行测试,使用记录块从4k到16M,测试文件大小从64k到512M
  • $ iozone -Ra 或 iozone -Rab output.xls
    iozone将测试结果放在Excel中
  • $ iozone -Ra -g 2g
    如果内存大于512MB,则测试文件需要更大;最好测试文件是内存的两倍。例如内存为1G,将测试文件设置最大为2G

$ iozone -Ra -g 2g -i 0 -i 1

如果只关心文件磁盘的read/write性能,而不必花费时间在其他模式上测试,则我们需要指定测试模式

$ iozone -Rac

如果测试NFS,将使用-c,这通知iozone在测试过程中执行close()函数。使用close()将减少NFS客户端缓存的影响。但是如果测试文件比内存大,就没有必要使用参数-c

-a  在所有模式下进行测试,使用记录块从4k到16M,测试文件大小从64k到512M
-b  生成excel文件
-R  生成excel输入
-f  指定临时文件名
-g  自动模式的最大文件大小
-n  自动模式的最小文件大小
-s  指定文件大小,默认单位是KB, 也可以使用m 和 g
-y  自动模式的最小记录大小,默认单位是KB
-q  自动模式的最大记录大小,默认单位是KB
-r  指定记录大小,单位是KB
-i  选择测试模式

0=write/rewrite
1=read/re-read
2=random-read/write
3=Read-backwards
4=Re-write-record
5=stride-read
6=fwrite/re-fwrite
7=fread/Re-fread,
8=random mix
9=pwrite/Re-pwrite
10=pread/Re-pread
11=pwritev/Re-pwritev
12=preadv/Repreadv

一个例子

$ iozone -a -s 128M -y 512 -q 16384 -i 0 -i 1 -i 2 -f /test/a.out -Rb /root/ext3_writeback.out

调整I/O调度算法

[root@c37 queue]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]
centos6.x默认为cfq
调整为deadline
[root@c37 queue]# echo deadline > /sys/block/sda/queue/scheduler
[root@c37 queue]# cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq
** I/O调度算法介绍 **

  1. CFQ(完全公平排队I/O调度程序) 默认
    特点:
    CFQ试图均匀地分布对I/O带宽的访问,避免进程被饿死并实现较低的延迟,是deadline和as调度器的折中.
    CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级的进程的读写不能自动地继承高的I/O优先级.
    工作原理:
    CFQ为每个进程/线程,单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,
    以此来保证每个进程都能被很好的分配到I/O带宽.I/O调度器每次执行一个进程的4次请求.
  2. NOOP(电梯式调度程序)
    特点:
    在Linux2.4或更早的版本的调度程序,那时只有这一种I/O调度算法.
    NOOP实现了一个简单的FIFO队列,它像电梯的工作主法一样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质.
    NOOP倾向饿死读而利于写.
    NOOP对于闪存设备,RAM,嵌入式系统是最好的选择.
    电梯算法饿死读请求的解释:
    因为写请求比读请求更容易.
    写请求通过文件系统cache,不需要等一次写完成,就可以开始下一次写操作,写请求通过合并,堆积到I/O队列中.
    读请求需要等到它前面所有的读操作完成,才能进行下一次读操作.在读操作之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求.
  3. Deadline(截止时间调度程序)
    特点:
    通过时间以及硬盘区域进行分类,这个分类和合并要求类似于noop的调度程序.
    Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限.这样就防止了写操作因为不能被读取而饿死的现象.
    Deadline对数据库环境(ORACLE RAC,MYSQL等)是最好的选择.
  4. AS(预料I/O调度程序)
    特点:
    本质上与Deadline一样,但在最后一次读操作后,要等待6ms,才能继续进行对其它I/O请求进行调度.
    可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价.
    它会在每个6ms中插入新的I/O操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量.
    AS适合于写入较多的环境,比如文件服务器
    AS对数据库环境表现很差.
    ** I/O调度算法总结 **
    Anticipatory I/O scheduler 适用于大多数环境,但不太合适数据库应用
    Deadline I/O scheduler
    通常与Anticipatory相当,但更简洁小巧,更适合于数据库应用, DATA/SAS盘
    CFQ I/O scheduler
    为所有进程分配等量的带宽,适合于桌面多任务及多媒体应用,默认IO调度器
    NOOP I/O scheduler 适用于SSD盘,有RAID卡,做了READ的盘

** sysctl.conf针对磁盘优化 **
vm.swappiness = [0 – 10] 默认是60,太高了,如果是缓存服务器建议配置为0

Linux整体I/O体系可以分为七层,它们分别是:

ionice

ionice可以更改任务的类型和优先级,不过只有cfq调度程序可以用ionice。

有三个例子说明ionice的功能:

  1. 采用cfq的实时调度,优先级为7
    ionice -c1 -n7 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&
  2. 采用缺省的磁盘I/O调度,优先级为3
    ionice -c2 -n3 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&
  3. 采用空闲的磁盘调度,优先级为0
    ionice -c3 -n0 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&

ionice的三种调度方法,实时调度最高,其次是缺省的I/O调度,最后是空闲的磁盘调度
ionice的磁盘调度优先级有8种,最高是0,最低是7
注意,磁盘调度的优先级与进程nice的优先级没有关系
一个是针对进程I/O的优先级,一个是针对进程CPU的优先级


  • Anticipatory I/O scheduler
    适用于大多数环境,但不太合适数据库应用。

  • Deadline I/O scheduler
    通常与Anticipatory相当,但更简洁小巧,更适合于数据库应用。

  • CFQ I/O scheduler
    默认IO调度器Default I/O
    scheduler,为所有进程分配等量的带宽,适合于桌面多任务及多媒体应用。

vm.swapness

这个参数涉及Linux对swap分区的使用.vm.swapness设置为0时,使得linux最大限度的使用物理内存.当物理内存不足时再使用swap分区.设置为100时,表示积极使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。centos的基本默认设置为30

[root@master etc]# cat /proc/sys/vm/swappiness
30

100-30=70%.当内存空间使用70%时,linux开始使用swap分区.当系统开始使用swap分区时候,mysql的性能将会受到很大的影响.建议将这个值设置为0,这个值得也是在/etc/sysctl.conf文件中.

Linus Elevator

早先的 IO 调度器就叫做 Linus
Elevator,当一个请求被加入到请求队列中,它首先检查队列中是否存在相邻的请求以合并两个请求,这可能包含前合并和后合并。如果不能合并,则寻找是否能够将新请求按扇区顺序插入到请求队列,如果没有找到适合插入的位置,那么就将这个请求插入到队列的末尾。另外,如果请求队列中的某个请求超过的预先定义的过期阈值,新请求即使可以进行排序,也被插入到队列的末尾。这样可以防止磁盘上某个区域产生大量请求,而其他区域的请求被饿死。然而,这种过期策略并不十分高效。

这种算法可能导致请求饿死的情况,它是 Linux 2.4 的唯一调度器。

当一个请求加入到请求队列时,IO 调度器所完成的操作如下

  1. 如果队列中存在对相邻扇区的请求,则合并两个请求为一个
  2. 如果队列中存在超过过期时间的请求,那么新请求被插入到队列的末尾,以防止饿死老的请求
  3. 如果队列中存在可以按扇区地址排序的合适位置,那么将请求插入到这个位置
  4. 如果队列中没有合适的可插入位置,请求被插入到队列末尾

文件系统优化

** 动态调整请求队列数来提高效率,默认请求队列数为:128, 可配置512
**
[root@c37 queue]# cat /sys/block/sda/queue/nr_requests
128
** read_ahead,
通过数据预读并且记载到随机访问内存方式提高磁盘读操作,默认值
128,ceph配置:8192 **
[root@c37 queue]# cat /sys/block/sda/queue/read_ahead_kb
128
** 关闭最后一次访问文件(目录)的时间戳 **
例如:
mount -t xfs -o defaults,noatime,nodiratime /dev/sda5 /data
** 大文件,大容量,大量文件数建议使用xfs文件系统 **

清单4.使用grubby命令

目录

shmall和shmmax

shmall linux中设允许使用的最大共享内存
shmmax linux中单个段允许使用的最大内存
shmmax理论上可以说设置为物理内存-1字节大小.如果这个值设置太小会影响mysql的性能.对于oracle来说如果这个值设置小于sga+pga,可能会造成oracle启动不了.
shmall=(shmmax)/4k(getconf PAGESIZE可得到)  getconf
PAGESIZE获取内存页的大小

修改这个值位于/etc/sysctl.conf文件中.想使这个修改的值生效除了通过使用重启系统外还可以通过以下命令:

##系统生效命令
sysctl -p
###查看系统值
ipcs -l
###查看实际使用情况
ipcs -u

read-ahead 预读

Linux
把读模式分为随机读和顺序读两大类,并只对顺序读进行预读。这一原则相对保守,但是可以保证很高的预读命中率。

为了保证预读命中率,Linux只对顺序读 (sequential read)
进行预读。内核通过验证如下两个条件来判定一个 read() 是否顺序读:

  1. 这是文件被打开后的第一次读,并且读的是文件首部;
  2. 当前的读请求与前一(记录的)读请求在文件内的位置是连续的。

如果不满足上述顺序性条件,就判定为随机读。任何一个随机读都将终止当前的顺序序列,从而终止预读行为(而不是缩减预读大小)。

I/O调度器的选择

I/O调度程序的测试

本次测试分为只读,只写,读写同时进行。
分别对单个文件600MB,每次读写2M,共读写300次。
1.测试磁盘读

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.81189 seconds, 92.4 MB/s
real 0m6.833s
user 0m0.001s
sys 0m4.556s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.61902 seconds, 95.1 MB/s
real 0m6.645s
user 0m0.002s
sys 0m4.540s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 8.00389 seconds, 78.6 MB/s
real 0m8.021s
user 0m0.002s
sys 0m4.586s
[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 29.8 seconds, 21.1 MB/s
real 0m29.826s
user 0m0.002s
sys 0m28.606s

测试结果
第一 noop用了6.61902秒,速度为95.1MB/s
第二 deadline用了6.81189秒,速度为92.4MB/s
第三 anticipatory用了8.00389秒,速度为78.6MB/s
第四 cfq用了29.8秒,速度为21.1MB/s

2.测试写磁盘

[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.93058 seconds, 90.8 MB/s
real 0m7.002s
user 0m0.001s
sys 0m3.525s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.79441 seconds, 92.6 MB/s
real 0m6.964s
user 0m0.003s
sys 0m3.489s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 9.49418 seconds, 66.3 MB/s
real 0m9.855s
user 0m0.002s
sys 0m4.075s
[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.84128 seconds, 92.0 MB/s
real 0m6.937s
user 0m0.002s
sys 0m3.447s

测试结果
第一 anticipatory用了6.79441秒,速度为92.6MB/s
第二 deadline用了6.84128秒,速度为92.0MB/s
第三 cfq用了6.93058秒,速度为90.8MB/s
第四 noop用了9.49418秒,速度为66.3MB/s

3.测试同时读/写

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 15.1331 seconds, 41.6 MB/s
[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 36.9544 seconds, 17.0 MB/s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 23.3617 seconds, 26.9 MB/s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 17.508 seconds, 35.9 MB/s

测试结果
第一 deadline用了15.1331秒,速度为41.6MB/s
第二 noop用了17.508秒,速度为35.9MB/s
第三 anticipatory用了23.3617秒,速度为26.9MS/s
第四 cfq用了36.9544秒,速度为17.0MB/s

内核相关参数

本文的大部分内容来自 IBM Redbook – Linux Performance and Tuning
Guidelines

清单3的命令把noop设置为一个磁盘的I/O调度器,你可以随时更改而无需重启计算机。

  • I/O调度的4种算法
  • I/O调度程序的测试
  • ionice

DEADLINE

DEADLINE在CFQ的基础上,解决了IO请求饿死的极端情况。除了CFQ本身具有的IO排序队列之外,DEADLINE额外分别为读IO和写IO提供了FIFO队列。读FIFO队列的最大等待时间为500ms,写FIFO队列的最大等待时间为5s。FIFO队列内的IO请求优先级要比CFQ队列中的高,,而读FIFO队列的优先级又比写FIFO队列的优先级高。优先级可以表示如下:
FIFO(Read) > FIFO(Write) > CFQ

dd

$ dd bs=1M count=128 if=/dev/zero of=test conv=fdatasync

使用这个参数,dd命令执行到最后会真正执行一次同步(sync)操作

$ dd bs=1M count=128 if=/dev/zero of=test oflag=direct 使用直接IO(绕过缓存)

# cat /sys/block/sda/queue/scheduler noop deadline [cfq] 

字段定义

/etc/fstab 文件包含了如下字段,通过空格或 Tab 分隔:

<file system>   <dir>   <type>  <options>   <dump>  <pass>

<file systems> – 要挂载的分区或存储设备.
<dir> – <file systems>的挂载位置。
<type> –
要挂载设备或是分区的文件系统类型,支持许多种不同的文件系统:ext2, ext3,
ext4, reiserfs, xfs, jfs, smbfs, iso9660, vfat, ntfs, swap 及 auto。
设置成auto类型,mount 命令会猜测使用的文件系统类型,对 CDROM 和 DVD
等移动设备是非常有用的。
<options> – 挂载时使用的参数,注意有些mount
参数是特定文件系统才有的。一些比较常用的参数有:
    auto – 在启动时或键入了 mount -a 命令时自动挂载。
    noauto – 只在你的命令下被挂载。
    exec – 允许执行此分区的二进制文件。
    noexec – 不允许执行此文件系统上的二进制文件。
    ro – 以只读模式挂载文件系统。
    rw – 以读写模式挂载文件系统。
    user – 允许任意用户挂载此文件系统,若无显示定义,隐含启用 noexec,
nosuid, nodev 参数。
    users – 允许所有 users 组中的用户挂载文件系统.
    nouser – 只能被 root 挂载。
    owner – 允许设备所有者挂载.
    sync – I/O 同步进行。
    async – I/O 异步进行。
    dev – 解析文件系统上的块特殊设备。
    nodev – 不解析文件系统上的块特殊设备。
    suid – 允许 suid 操作和设定 sgid
位。这一参数通常用于一些特殊任务,使一般用户运行程序时临时提升权限。
    nosuid – 禁止 suid 操作和设定 sgid 位。
    noatime – 不更新文件系统上 inode 访问记录,可以提升性能(参见 atime
参数)。
    nodiratime – 不更新文件系统上的目录 inode
访问记录,可以提升性能(参见 atime 参数)。
    defaults – 使用文件系统的默认挂载参数,例如 ext4 的默认参数为:rw,
suid, dev, exec, auto, nouser, async.
    relatime – 实时更新 inode access
记录。只有在记录中的访问时间早于当前访问才会被更新。(与 noatime
相似,但不会打断如 mutt
或其它程序探测文件在上次访问后是否被修改的进程。),可以提升性能(参见
atime 参数)。
    flush – vfat
的选项,更频繁的刷新数据,复制对话框或进度条在全部数据都写入后才消失。
<dump> dump 工具通过它决定何时作备份. dump
会检查其内容,并用数字来决定是否对这个文件系统进行备份。 允许的数字是 0
和 1 。0 表示忽略, 1 则进行备份。大部分的用户是没有安装 dump 的
,对他们而言 <dump> 应设为 0。
<pass> fsck 读取 <pass>
的数值来决定需要检查的文件系统的检查顺序。允许的数字是0, 1, 和2。
根目录应当获得最高的优先权 1, 其它所有需要被检查的设备设置为 2. 0
表示设备不会被 fsck 所检查。

VFS(Virtual FileSystem) 虚拟文件系统

文件系统是内核的功能,是一种工作在内核空间的软件,访问一个文件必须要需要文件系统的存在才可以。Linux
可以支持多达数十种不同的文件系统,它们的实现各不相同,因此 Linux
内核向用户空间提供了虚拟文件系统这个统一的接口用来对文件系统进行操作。

威尼斯城真人赌钱网站 1

虚拟文件系统是位于用户空间进程和内核空间中多种不同的底层文件系统的实现之间的一个抽象的接口层,它提供了常见的文件系统对象模型(如
i-node, file object, page cache, directory entry,
etc.)和访问这些对象的方法(如 open, close, delete, write, read, create,
fstat,
etc.),并将它们统一输出,类似于库的作用。从而向用户进程隐藏了各种不同的文件系统的具体实现,这样上层软件只需要和
VFS 进行交互而不必关系底层的文件系统,简化了软件的开发,也使得 linux
可以支持多种不同的文件系统。

在2.4
内核中它是第一种I/O调度器。它的主要作用是为每个设备维护一个查询请求,当内核收到一个新请求时,如果能合并就合并。如果不能合并,就会尝试排序。如果既不能合并,也没有合适的位置插入,就放到请求队列的最后。

I/O调度的4种算法

1.CFQ(完全公平排队I/O调度程序)

  • 特点:
    在最新的内核版本和发行版中,都选择CFQ做为默认的I/O调度器,对于通用的服务器也是最好的选择。
    CFQ试图均匀地分布对I/O带宽的访问,避免进程被饿死并实现较低的延迟,是deadline和as调度器的折中。
    CFQ对于多媒体应用(video,audio)和桌面系统是最好的选择。
    CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级的进程的读写不能自动地继承高的I/O优先级。
  • 工作原理:
    CFQ为每个进程/线程,单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每个进程都能被很好的分配到I/O带宽.I/O调度器每次执行一个进程的4次请求。

2.NOOP(电梯式调度程序)

  • 特点:
    在Linux2.4或更早的版本的调度程序,那时只有这一种I/O调度算法。
    NOOP实现了一个简单的FIFO队列,它像电梯的工作主法一样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质。
    NOOP倾向饿死读而利于写。
    NOOP对于闪存设备,RAM,嵌入式系统是最好的选择。

电梯算法饿死读请求的解释:
因为写请求比读请求更容易。
写请求通过文件系统cache,不需要等一次写完成,就可以开始下一次写操作,写请求通过合并,堆积到I/O队列中。
读请求需要等到它前面所有的读操作完成,才能进行下一次读操作.在读操作之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求。

3.Deadline(截止时间调度程序)

  • 特点:
    通过时间以及硬盘区域进行分类,这个分类和合并要求类似于noop的调度程序。
    Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限.这样就防止了写操作因为不能被读取而饿死的现象。
    Deadline对数据库环境(ORACLE RAC,MYSQL等)是最好的选择。

4.AS(预料I/O调度程序)

  • 特点:
    本质上与Deadline一样,但在最后一次读操作后,要等待6ms,才能继续进行对其它I/O请求进行调度。
    可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价。
    它会在每个6ms中插入新的I/O操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量。
    AS适合于写入较多的环境,比如文件服务器。
    AS对数据库环境表现很差。

查看当前系统支持的IO调度算法

[root@localhost ~]# dmesg | grep -i scheduler
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)

查看当前系统的I/O调度方法

cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

临地更改I/O调度方法

#例如:想更改到noop电梯调度算法:
echo noop > /sys/block/sda/queue/scheduler

想永久的更改I/O调度方法

#修改内核引导参数,加入elevator=调度程序名
vi /boot/grub/menu.lst
#更改到如下内容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet

重启之后,查看调度方法

cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq
#已经是deadline了

ANTICIPATORY

CFQ和DEADLINE考虑的焦点在于满足零散IO请求上。对于连续的IO请求,比如顺序读,并没有做优化。为了满足随机IO和顺序IO混合的场景,Linux还支持ANTICIPATORY调度算法。ANTICIPATORY的在DEADLINE的基础上,为每个读IO都设置了6ms的等待时间窗口。如果在这6ms内OS收到了相邻位置的读IO请求,就可以立即满足。

对应磁盘io的调度算法保存在/sys/block/<devname>/queue/scheduler文件中通过以下命令修改对应磁盘的调度算法

echo <scheulername> > /sys/block/devname/queue/scheduler
##数据库中建议使用DEADLINE调度算法

I/O子系统架构

威尼斯城真人赌钱网站 2

上图概括了一次磁盘 write 操作的过程,假设文件已经被从磁盘中读入了 page
cache 中

  1. 一个用户进程通过 write() 系统调用发起写请求
  2. 内核更新对应的 page cache
  3. pdflush 内核线程将 page cache 写入至磁盘中
  4. 文件系统层将每一个 block buffer 存放为一个 bio
    结构体,并向块设备层提交一个写请求
  5. 块设备层从上层接受到请求,执行 IO 调度操作,并将请求放入IO
    请求队列中
  6. 设备驱动(如 SCSI 或其他设备驱动)完成写操作
  7. 磁盘设备固件执行对应的硬件操作,如磁盘的旋转,寻道等,数据被写入到磁盘扇区中

清单3. 查使用shell命令

noop

NOOP算法的全写为No
Operation。该算法实现了最最简单的FIFO队列,所有IO请求大致按照先来后到的顺序进行操作。之所以说“大致”,原因是NOOP在FIFO的基础上还做了相邻IO请求的合并,并不是完完全全按照先进先出的规则满足IO请求。
假设有如下的io请求序列:
100,500,101,10,56,1000
NOOP将会按照如下顺序满足:
100(101),500,10,56,1000

文件系统

一般来说 ReiserFS 更适合于小文件 IO,而 XFS 和 JFS 适合大文件 IO,ext4
则处于两种之间。

JFS 和 XFS 适用于大型的数据仓库,科学计算,大型 SMP
服务器,多媒体流服务等。ReiserFS 和 Ext4 适合于文件服务器,Web
服务器或邮件服务器。

5 NOOP

文件系统示例

#
# /etc/fstab
# Created by anaconda on Sun Oct 15 15:19:00 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=eb448abb-3012-4d8d-bcde-94434d586a31 /                       ext4    defaults        1 1
UUID=c0ae5412-80c2-4576-9ad2-ee927aab8dc9 /spiderData             ext4    defaults        1 2
UUID=ff658182-13b5-4d66-80ab-8bef7177e96f /wikiData               ext4    defaults        1 2
UUID=a7bae13a-16e2-4290-a4b2-97558d48750e /docker                 ext4    defaults        1 2
UUID=ad4ae494-b010-40c6-8b0b-5a68034a2b9f /dockertemp             ext4    defaults        1 2

FileSystem

CFQ全称Completely Fair Scheduler ,中文名称完全公平调度器,它是现在许多
Linux
发行版的默认调度器,CFQ是内核默认选择的I/O调度器。它将由进程提交的同步请求放到多个进程队列中,然后为每个队列分配时间片以访问磁盘。对于通用的服务器是最好的选择,CFQ均匀地分布对I/O带宽的访问。CFQ为每个进程和线程,单独创建一个队列来管理该进程所产生的请求,以此来保证每个进程都能被很好的分配到I/O带宽,I/O调度器每次执行一个进程的4次请求。该算法的特点是按照I/O请求的地址进行排序,而不是按照先来后到的顺序来进行响应。简单来说就是给所有同步进程分配时间片,然后才排队访问磁盘,CFQ的工作流程如图
3 所示 。

cfq(默认的磁盘调度算法)

CFQ算法的全写为Completely Fair
Queuing。该算法的特点是按照IO请求的地址进行排序,而不是按照先来后到的顺序来进行响应。
假设有如下的io请求序列:
100,500,101,10,56,1000
CFQ将会按照如下顺序满足:
100,101,500,1000,10,56

在传统的SAS盘上,磁盘寻道花去了绝大多数的IO响应时间。CFQ的出发点是对IO地址进行排序,以尽量少的磁盘旋转次数来满足尽可能多的IO请求。在CFQ算法下,SAS盘的吞吐量大大提高了。但是相比于NOOP的缺点是,先来的IO请求并不一定能被满足,可能会出现饿死的情况。

Complete Fair Queuing(CFQ)- fairness-oriented

CFQ 为每个进程分配一个 I/O
请求队列,在每个队列的内部,进行合并和排序的优化。CFQ
以轮询的方式处理这些队列,每次从一个队列中处理特定数量的请求(默认为 4
个)。它试图将 I/O 带宽均匀的分配至每个进程。CFQ
原本针对的是多媒体或桌面应用场景,然而,CFQ
其实在许多场景中内表现的很好。CFQ 对每一个 IO 请求都是公平的。这使得 CFQ
很适合离散读的应用 (eg: OLTP DB)

多数企业发型版选择 CFQ 作为默认的 I/O 调度器。

查看某块硬盘的IO调度算法I/O调度器,使用如下命令:

文件系统

Linux文件系统主要ext3,ext4,xfs几种类型的文件系统.其中xfs的文件系统的性能据传说大于ext3和ext4这两类文件系统.文件系统相关配置在/etc/fstab文件夹中.系统启动的时候,系统会自动地从这个文件读取信息,并且会自动将此文件中指定的文件系统挂载到指定的目录。

NOOP(No Operation)

该算法实现了最简单的 FIFO 队列,所有 IO
请求按照大致的先后顺序进行操作。之所以说「大致」,原因是 NOOP 在 FIFO
的基础上还做了相邻 IO 请求的合并,但其不会进行排序操作。

NOOP
适用于底层硬件自身就具有很强调度控制器的块设备(如某些SAN设备),或者完全随机访问的块设备(如SSD)。

各个调度器在数据库应用下的性能,可以看出CFQ的性能是比较均衡的

威尼斯城真人赌钱网站 3

清单2. 查看一个硬盘使用的I/O调度器

磁盘调度算法的选择

磁盘的调度算法有cfq(公平调度),noop,deadline,anticipatory

blktrace & blkparse

blktrace 是一个针对 Linux 内核中块设备 IO 层的跟踪工具,用来收集磁盘IO
信息中当 IO 进行到块设备层(block层,所以叫blk trace)时的详细信息(如
IO 请求提交,入队,合并,完成等等一些列的信息),blktrace
需要借助内核经由 debugfs 文件系统(debugf
s文件系统在内存中)来输出信息,所以用 blktrace 工具之前需要先挂载
debugfs 文件系统,blktrace需要结合 blkparse 来使用,由 blkparse 来解析
blktrace 产生的特定格式的二进制数据。

blktrace语法:

blktrace -d dev [ -r debugfs_path ] [ -o output ] [-k ] [ -w time ] [ -a action ] [ -A action_mask ] [ -v ]

blktrace选项:
 -A hex-mask        #设置过滤信息mask成十六进制mask
 -a mask            #添加mask到当前的过滤器
 -b size            #指定缓存大小for提取的结果,默认为512KB
 -d dev         #添加一个设备追踪
 -I file            #Adds the devices found in file as devices to trace
 -k             #杀掉正在运行的追踪
 -n num-sub     #指定缓冲池大小,默认为4个子缓冲区 
 -o file            #指定输出文件的名字
 -r rel-path        #指定的debugfs挂载点
 -V             #版本号 
 -w seconds     #设置运行的时间

文件输出

$ blktrace –d /dev/sda –o trace

解析结果 $ blkparse -i trace -o /root/trace.txt

清单 1. 查看当前系统支持的I/O调度器

/etc/security/limits.conf

* soft noprofile 65536
* hard noprofile 65536

* 所用用户都生效
soft和hard分别表示软限制和硬限制.soft是指当前系统生效设置,
hard系统中所能设定的最大值
noprofile 可打开的最大的文件描述符
对应的其他参数可参考/etc/security/limits.conf文件中的说明

相关文章