一、问题分析:

通过跟踪定位write系统调用的实现发现,在每次调用a_ops->write_end之后,都会去调用balance_dirty_pages_ratelimited,该函数负责检查当前系统总的脏页数是否超过阀值(ratelimit_pages),如果超过,就会去调用balance_dirty_pages去刷新脏页。ratelimit_pages表示每个cpu脏页的阀值,超过此阀值,balance_dirty_pages_ratelimited函数就会去查看是否需要强制回写脏页。
balance_dirty_pages函数会去读取系统物理内存全局的脏页数目、当前的后备存储器(如磁盘)上的脏页数目,并与其阀值做比较,从而判断是否需要回写脏页,主要的代码如下:

for (;;) {
dirty_exceeded =
(bdi_nr_reclaimable + bdi_nr_writeback > bdi_thresh)
|| (nr_reclaimable + nr_writeback > dirty_thresh); if (!dirty_exceeded)
break; if (!bdi->dirty_exceeded)
bdi->dirty_exceeded = 1; if (bdi_nr_reclaimable > bdi_thresh) {
writeback_inodes_wb(&bdi->wb, &wbc);
pages_written += write_chunk - wbc.nr_to_write;
trace_wbc_balance_dirty_written(&wbc, bdi);
if (pages_written >= write_chunk)
break; /* We've done our duty */
} __set_current_state(TASK_UNINTERRUPTIBLE);
io_schedule_timeout(pause); pause <<= 1;
if (pause > HZ / 10)
pause = HZ / 10;
}

bdi_nr_reclaimable:当前后备存储器的脏页数目。

bdi_nr_writeback:当前后备存储器正在回写的脏页数目。

bdi_thresh:当前后备存储区的脏页阀值,超过此阀值就需要回写脏页。

nr_reclaimable:系统全局的脏页数目。

nr_writeback:系统全局的正在回写的脏页数目。

dirty_thresh:系统全局的脏页阀值。

上述代码中dirty_exceeded的计算可能出现下面的这种情况:

nr_reclaimable + nr_writeback > dirty_thresh

bdi_nr_reclaimable + bdi_nr_writeback < bdi_thresh

这种情况下dirty_exceeded=1,此时系统中全局的脏页数目超过阀值,但是当前后备存储器的脏页数目并未超过阀值,此时该函数就会一直在此循环等待,等待后台flush线程定期的回写脏页,直到全局脏页数降低到阀值以下,该函数才会结束循环,而此时write系统调用才会返回,所以就会导致从应用层来看,写硬盘速度变慢。而此时的io_schedule_timeout会被计算到iowait中,所以会出现iowait 100%的情况。

这种做法是很不合理的,内核把所有磁盘的脏页全局对待了,没有严格按照目标磁盘来划分,如果当时系统比较忙,全局的脏页数超过了阀值,所有需要写盘的进程都需要等待,直到脏页的数量降低至阀值以下,这样严重影响了系统写盘的性能。在出现上述情况时,当前磁盘的脏页数目低于阀值,应该立刻返回,根本不用等待脏页回写。

二、解决方法

1、通过调整proc下相关参数
/proc/sys/vm/dirty_ratio

这个参数控制一个进程在文件系统中的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,表示当一个进程中写缓冲使用到系统内存多少的时候,再有磁盘写操作时开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。

/proc/sys/vm/dirty_background_ratio

这个参数控制内核的flush进程何时刷新磁盘。单位是百分比,表示系统总内存的百分比,意思是当磁盘的脏数据达到系统内存多少的时候,flush开始把脏数据刷新到磁盘。增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。

/proc/sys/vm/dirty_writeback_centisecs

这个参数表明内核的flush线程每隔多久被唤醒并执行把脏数据写出到硬盘。单位是 1/100 秒。缺省数值是500,也就是 5秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。

/proc/sys/vm/dirty_expire_centisecs

这个参数声明Linux内核写缓冲区里面的脏数据多久了之后,flush 进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。

通过调整以上四个值,会提高硬盘的写速度,丢帧的数目也能降到一定的比例,但是始终无法彻底解决该问题。

2、在balance_dirty_pages中使用更加严格的判断机制

由于使用上述判断dirty_exceeded的机制,只要系统中存在多个IO目标设

备(后备存储器),如果1个目标设备性能出现降低,导致脏页回写变慢,就会严重影响到其他目标设备的性能。而实际上,应该把磁盘上的脏页分开来进行处理,只有各自的磁盘上累积的脏页比较多,才需要等待后台刷新,否则就可以直接跳出循环函数,继续写磁盘。而在linux3.2的版本上,应用了更加严格的判断dirty_exceeded的机制,参照高版本内核的修改,修改linux2.6.37的内核:

dirty_exceeded =

(bdi_nr_reclaimable + bdi_nr_writeback > bdi_thresh)

&& (nr_reclaimable + nr_writeback > dirty_thresh);

只有当前系统全局的脏页数超过阀值并且当前的磁盘脏页数目也超过阀值,才认为需要等待脏页的回写,否则,直接退出循环,继续进行后续的写操作。通过这种修改,只有在当前磁盘的脏页数目超过阀值,才会在当前磁盘上等待脏页回写。当系统中有多个后备存储器时,多个后备存储器之间互相不影响,各自管理各自的脏页数目,使系统对脏页的处理更加的合理。

from:http://sunjiangang.blog.chinaunix.net/uid-9543173-id-3571758.html

linux2.6.37内核接两个硬盘导致读写效率变低的问题的更多相关文章

  1. linux-2.6.26内核中ARM中断实现详解(转)

    转载:http://www.cnblogs.com/leaven/archive/2010/08/06/1794293.html 更多文档参见:http://pan.baidu.com/s/1dDvJ ...

  2. 【内核】linux2.6版本内核编译配置选项(二)

    目录 Linux2.6版本内核编译配置选项(一):http://infohacker.blog.51cto.com/6751239/1203633 Linux2.6版本内核编译配置选项(二):http ...

  3. 【内核】linux2.6版本内核编译配置选项(一)

    Linux 2.6.19.x 内核编译配置选项简介 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分发, ...

  4. Suse环境下编译linux-2.6.24内核

    Suse环境下编译linux-2.6.24内核 1.下载linux-2.6.24内核源码: https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/ ...

  5. raid5两块硬盘离线怎么办? 强制上线失败如何恢复数据

    服务器故障描述: 客户使用Dell 2850服务器组建了raid5磁盘阵列,阵列中包含有6块硬盘(SCSI硬盘,单盘容量300G),服务器操作系统为linux Redhat4:文件系统为ext3文件系 ...

  6. Raid5两块硬盘掉线可以恢复数据吗_raid数据恢复案例分享

    本案例中发生故障的存储类型是HP P2000,虚拟化平台为vmware exsi,共有10块硬盘组成raid5(硬盘容量为1t,其中6号盘是热备盘),由于某些故障导致阵列中两块硬盘亮黄灯掉线,硬盘无法 ...

  7. 6块300G SCSI RAID5,两块硬盘损坏的数据恢复总结

    [用户单位]XXXX网站[数据恢复故障描述]DELL POWEREDGE 2850服务器,内置6块300G SCSI硬盘 ,组成RAID5,安装LINUX REDHAT 4操作系统,存储大量照片,文件 ...

  8. 成功案例分享:raid5两块硬盘掉线数据丢失恢复方法

    1. 故障描述    本案例是HP P2000的存储vmware exsi虚拟化平台,由RAID-5由10块lT硬盘组成,其中6号盘是热备盘,由于故障导致RAID-5磁盘阵列的两块盘掉线,表现为两块硬 ...

  9. 如何用两块硬盘做磁盘阵列的教程Raid 1

    如今,市面上的大部分服务器都自带有阵列卡.只要有两块以上硬盘,我们就可以利用服务器自带的阵列卡做磁盘阵列.Raid 1 为例.Raid 1 是磁盘阵列的其中一个系列,将两块硬盘构成磁盘阵列,可以保证数 ...

随机推荐

  1. Delphi 10.2.3 + Xcode 9.2 开发 IOS 程序,免证书+免越狱,真机调试

    工具列表: 1,delphi 10.2.3 + PAServer19.0. 2,配置好一些的 PC 一台,建议至少 4 代 intel i5 + 16G + 256GSSD,低于此配置将产生拖延症. ...

  2. 【SQL.基础构建-第一节(1/4)】

    --        Tips:数据库与sql--    一.What's 数据库-- 1.数据库(Database,DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.--   ...

  3. Vue练手项目(包含typescript版本)

    本项目的git仓库https://github.com/lznism/xiachufang-vue 对应的使用typescript实现的版本地址https://github.com/lznism/xi ...

  4. 0312-css样式(选择器、文本text、字体fonts、背景background)

    问题: 1.css中table{border:1px:}是定义table的样式,只有表格的外边框,不能实现<table border="1"></table> ...

  5. 【BZOJ2809】【APIO2012】派遣

    Background 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. Description 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者 ...

  6. IO复用

    IO复用:使得程序能同时监听多个文件描述符 select: select在一段指定的时间内,监听用户感兴趣的文件描述符的 读.写.异常事件. select(int nfds,fd_set* readf ...

  7. hdu 5750 Dertouzos 素数

    Dertouzos Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  8. hdu 4283 区间dp

    You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. spring的@Transactional(rollbackFor=Exception.class)的使用

    Spring框架的事务基础架构代码将默认地只在抛出运行时和unchecked exceptions时才标识事务回滚. 也就是说,当抛出个RuntimeException 或其子类例的实例时.(Erro ...

  10. bootstrap的模态框

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...