linux 磁盘

转:https://www.cnblogs.com/shengs/p/5085980.htmlhtml

关于页面缓存的信息,能够用
cat /proc/meminfo 
看到。其中的Cached 指用于pagecache的内存大小(diskcache-SwapCache)。随着写入缓存页,Dirty 的值会增长。
一旦开始把缓存页写入硬盘,Writeback的值会增长直到写入结束。

Linux 用pdflush进程把数据从缓存页写入硬盘,查看有多少个pdflush进程
cat /proc/sys/vm/nr_pdflush_threads

pdflush的行为受/proc/sys/vm中的参数的控制
/proc/sys/vm/dirty_writeback_centisecs (default 500): 
1/100秒, 多长时间唤醒pdflush将缓存页数据写入硬盘。默认5秒唤醒2个(更多个)线程。
若是wrteback的时间长于dirty_writeback_centisecs的时间,可能会出问题。

pdflush的第一件事是读取
/proc/sys/vm/dirty_expire_centiseconds (default 3000)
1/100秒。缓存页里数据的过时时间(旧数据),在下一个周期内被写入硬盘。默认30秒是一个很长的时间。

第二件事是判断内存是否到了要写入硬盘的限额,由参数决定:
/proc/sys/vm/dirty_background_ratio (default 10)
百分值,保留过时页缓存(脏页缓存)的最大值。是以MmeFree+Cached-Mapped的值为基准的

pdflush写入硬盘看两个参数:
1 数据在页缓存中是否超出30秒,若是是,标记为脏页缓存;
2 脏页缓存是否达到工做内存的10%;

如下参数也会影响到pdflush
/proc/sys/vm/dirty_ratio (default 40)
总内存的最大百分比,系统所能拥有的最大脏页缓存的总量。超过这个值,开启pdflush写入硬盘。若是cache增加快于pdflush,那么整个系统在40%的时候遇到I/O瓶颈,全部的I/O都要等待cache被pdflush进硬盘后才能从新开始。

对于有高度写入操做的系统
dirty_background_ratio: 主要调整参数。若是须要把缓存持续的而不是一会儿大量的写入硬盘,下降这个值。
dirty_ratio:        第二调整参数。

Swapping参数
/proc/sys/vm/swappiness
默认,linux倾向于从物理内存映射到硬盘缓存,保持硬盘缓存尽量大。未用的页缓存会被放进swap区。
数值为0,将会避免使用swapping
100,将会尽可能使用swapping
少用swapping会增长程序的响应速度;多用swapping将会提升系统的可用性。

若是有大量的写操做,为避免I/O的长时间等待,能够设置:
$ echo 5 > /proc/sys/vm/dirty_background_ratio
$ echo 10 > /proc/sys/vm/dirty_ratio

文件系统数据缓冲须要频繁的内存分配。加大保留内存的值能提高系统速度和稳定。小于8G的内存,保留内存为64M,大于8G的设置为256M
$ echo 65536 > /proc/sys/vm/min_free_kbytes


I/O 调度器
cat /sys/block/[disk]/queue/scheduler

4中调度算法
noop anticipatory deadline [cfq] 
deadline :  deadline 算法保证对既定的IO请求以最小的延迟时间。
anticipatory: 有个IO发生后,若是又有进程请求IO,则产生一个默认6ms猜想时间,猜想下一个进程请求IO是干什么。这对于随机读取会形成较大的延时。
                     对数据库应用很糟糕,而对于Web Server等则会表现不错。
cfq:    对每一个进程维护一个IO队列,各个进程发来的IO请求会被cfq以轮循方式处理,对每个IO请求都是公平。适合离散读的应用。
noop: 对全部IO请求都用FIFO队列形式处理。默认IO不会存在性能问题。

改变调度器
$ echo deadline > /sys/block/sdX/queue/scheduler
对于数据库服务器,deadline算法是推荐的。

提升调度器请求队列的
$ echo 4096 > /sys/block/sdX/queue/nr_requests

有大量的读请求,默认的请求队列应付不过来,能够提升这个值。缺点是要牺牲必定的内存。
为了增长连续读取的吞吐量,能够增长预读数据量。预读的实际值是自适应的,因此使用一个较高的值,不会下降小型随机存取的性能。
$ echo 4096 > /sys/block/sdX/queue/read_ahead_kb
若是LINUX判断一个进程在顺序读取文件,那么它会提早读取进程所需文件的数据,放在缓存中。
  


服务器遇到磁盘写活动高峰,致使请求处理延迟很是大(超过3秒)。经过调整内核参数,将写活动的高峰分布成频繁的屡次写,每次写入的数据比较少。这样能够把尖峰的写操做削平成屡次写操做。以这种方式执行的效率比较低,由于内核不太有机会组合写操做。但对于繁忙的服务器,写操做将更一致地进行,并将极大地改进交互式性能。node

/proc/sys/vm/dirty_ratiopython

控制文件系统的写缓冲区的大小,单位是百分比,表示占系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也能够极大提升系统的写性能。可是,当你须要持续、恒定的写入场合时,应该下降其数值。linux

/proc/sys/vm/dirty_background_ratio

控制文件系统的pdflush进程,在什么时候刷新磁盘。单位是百分比,表示系统内存的百分比,pdflush用于将内存中的内容和文件系统进行同步,好比说,当一个文件在内存中进行修改,pdflush负责将它写回硬盘.每当内存中的垃圾页(dirty page)超过10%的时候,pdflush就会将这些页面备份回硬盘.增大之会使用更多系统内存用于磁盘写缓冲,也能够极大提升系统的写性能。可是,当你须要持续、恒定的写入场合时,应该下降其数值:ios

/proc/sys/vm/dirty_writeback_centisecs

控制内核的脏数据刷新进程pdflush的运行间隔。单位是 1/100 秒。缺省数值是500,也就是 5 秒。若是你的系统是持续地写入动做,那么实际上仍是下降这个数值比较好,这样能够把尖峰的写操做削平成屡次写操做。
若是你的系统是短时间地尖峰式的写操做,而且写入数据不大(几十M/次)且内存有比较多富裕,那么应该增大此数值。
该参数的设置应该小于dirty_expire_centisecs,但也不能过小,过小I/O太频繁,反而
使系统性能降低。具体可能须要在生产环境上测试。听说1:6 (dirty_expire_centisecs  : dirty_writeback_centisecs )的比例比较好。算法

/proc/sys/vm/dirty_expire_centisecs
数据库

声明Linux内核写缓冲区里面的数据多“旧”了以后,pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操做来讲,这个值适当缩小也是好的,但也不能缩小太多,由于缩小太多也会致使IO提升太快。
固然,若是你的系统内存比较大,而且写入模式是间歇式的,而且每次写入的数据不大(好比几十M),那么这个值仍是大些的好。api

/proc/sys/vm/vfs_cache_pressure
缓存

表示内核回收用于directory和inode   cache内存的倾向;缺省值100表示内核将根据pagecache和swapcache,把directory和inode   cache保持在一个合理的百分比;下降该值低于100,将致使内核倾向于保留directory和inode   cache;增长该值超过100,将致使内核倾向于回收directory和inode   cache服务器

/proc/sys/vm/min_free_kbytes

表示强制Linux   VM最低保留多少空闲内存(Kbytes)。
缺省设置:724(512M物理内存)

/proc/sys/vm/nr_pdflush_threads

表示当前正在运行的pdflush进程数量,在I/O负载高的状况下,内核会自动增长更多的pdflush进程。

/proc/sys/vm/overcommit_memory

指定了内核针对内存分配的策略,其值能够是0、一、2。

0,   表示内核将检查是否有足够的可用内存供应用进程使用;若是有足够的可用内存,内存申请容许;不然,内存申请失败,并把错误返回给应用进程。

1,   表示内核容许分配全部的物理内存,而无论当前的内存状态如何。

2,   表示内核容许分配超过全部物理内存和交换空间总和的内存(参照overcommit_ratio)。

缺省设置:0

/proc/sys/vm/overcommit_ratio

若是overcommit_memory=2,能够过载内存的百分比,经过如下公式来计算系统总体可用内存。系统可分配内存=交换空间+物理内存*overcommit_ratio/100
缺省设置:50(%)

/proc/sys/vm/page-cluster

表示在写一次到swap区的时候写入的页面数量,0表示1页,1表示2页,2表示4页。
缺省设置:3(2的3次方,8页)

/proc/sys/vm/swapiness

表示系统进行交换行为的程度,数值(0-100)越高,越可能发生磁盘交换。

更改:
/etc/sysctl.conf

vm.dirty_ratio = 40

sysctl -p

查看:

find /proc/sys/vm -name dirty* -print | while read name; do echo $name ;cat ${name}; done
  • 磁盘检测
  • (1)使用hdparm命令检测读取速度:
        hdparm命令提供了一个命令行的接口用于读取和设置IDE和SCSI硬盘参数。
        安装:
            yum install hdparm
        语法:
            hdparm(选项)(参数)
        
        经常使用选项:
            -f: 将内存缓冲区的数据写入硬盘,并清除缓冲区;
            -g: 显示硬盘的磁轨,磁头,磁区等参数;
            -i: 显示硬盘的硬件规格信息,这些信息是在开机时由硬盘自己所提供;
            -I: 直接读取硬盘所提供的硬件规格信息;
            -t: 评估硬盘的读取效率;
            -T: 评估硬盘快取的读取效率;
        参数:
            设备文件:指定id驱动对应的设备文件名
            
        实例:
            使用方法很简单,hdparm -Tt /dev/sda
            
    [root@super python]# hdparm -Tt /dev/sda


    /dev/sda:
     Timing cached reads:   8470 MB in  2.00 seconds = 4235.83 MB/sec        # 硬盘的快取读取速度,2.00秒读取了8470 MB,平均每秒读取:4235.83 MB/sec
     Timing buffered disk reads: 722 MB in  3.22 seconds = 224.28 MB/sec    # 硬盘的读取速度:3.22秒读取了722 MB,平均每秒读取:224.28 MB/sec
     
    (2) 使用dd命令测试写入速度:
        dd命令是一个不太专业的测速工具,若是要求的不是很严格,仍是能够进行屡次测试来获得一个近似值的。
        安装:
            yum install coreutils
        实例:
            [root@super python]# dd if=/dev/zero of=test bs=1M count=2048        # 写入一个文件名test, bytes 为1M,共2048 blocks 的文件,总共大小为:1M * 2048 = 2G
            记录了2048+0 的读入
            记录了2048+0 的写出
            2147483648字节(2.1 GB)已复制,88.8786 秒,24.2 MB/秒
            
            88.8786 秒写入了2.1 GB数据,平均:24.2 MB/秒

  • #iostat -x 1
    avg-cpu:%user%nice%sys%idle
    16.240.004.3179.44
    Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
    /dev/cciss/c0d0
    0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
    /dev/cciss/c0d0p1
    0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
    /dev/cciss/c0d0p2
    0.000.000.000.000.000.000.000.000.000.000.000.000.00

    上面的iostat输出代表秒有28.57次设备I/O操做:总IO(io)/s=r/s(读)+w/s(写)=1.02+27.55=28.57(次/秒)其中写操做占了主体(w:r=27:1)。

    平均每次设备I/O操做只须要5ms就能够完成,但每一个I/O请求却须要等上78ms,为何?由于发出的I/O请求太多(每秒钟约29个),假设这些请求是同时发出的,那么平均等待时间能够这样计算:

    平均等待时间=单个I/O服务时间*(1+2+…+请求总数-1)/请求总数

    应用到上面的例子:平均等待时间=5ms*(1+2+…+28)/29=70ms,和iostat给出的78ms的平均等待时间很接近。这反过来代表I/O是同时发起的。

    每秒发出的I/O请求不少(约29个),平均队列却不长(只有2个左右),这代表这29个请求的到来并不均匀,大部分时间I/O是空闲的。

    一秒中有14.29%的时间I/O队列中是有请求的,也就是说,85.71%的时间里I/O系统无事可作,全部29个I/O请求都在142毫秒以内处理掉了。

    delta(ruse+wuse)/delta(io)=await=78.21=>delta(ruse+wuse)/s=78.21*delta(io)/s=78.21*28.57=2232.8,代表每秒内的I/O请求总共须要等待2232.8ms。因此平均队列长度应为2232.8ms/1000ms=2.23,而iostat给出的平均队列长度(avgqu-sz)却为22.35,为何?!由于iostat中有bug,avgqu-sz值应为2.23,而不是22.35。

相关文章
相关标签/搜索