cgroup其他部分 IO + hugepage
cgroup还有其他一些限制特性,如io,pid,hugetlb等,这些用处不多,参见Cgroupv1。下面介绍下与系统性能相关的io和hugepage,cgroup的io介绍参考Cgroup - Linux的IO资源隔离 linux IO linux io涉及到对文件(磁盘设备)的读写性能,对io的优化主要分为
使用如下命令查看当前系统支持的调度器 # dmesg | grep -i scheduler [ 1.343756] io scheduler noop registered [ 1.343759] io scheduler deadline registered (default) [ 1.343784] io scheduler cfq registered [ 1.343787] io scheduler mq-deadline registered [ 1.343789] io scheduler kyber registered 使用如下命令查看当前磁盘支持的调度器,方括号表示当前生效的调度器 # cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
调度器的参数位于 Noop:该算法实现了最简单的FIFO队列,所有I/O请求大致按照先来后到的顺序进行操作,特别适用于固态硬盘
CFQ:给所有进程分配等同的块设备使用的时间片,进程在时间片内,可以将产生的IO请求提交给块设备进行处理,时间片结束,进程的请求将排进它自己的队列,等待下次调度的时候进行处理,适用于通用服务器。 Deadline:保证每个IO请求在一定的时间内一定要被服务到,以此来避免某个请求饥饿,deadline在大多数多线程应用场景和数据库应用场景下表现的性能要优于cfq 可以通过直接修改/sys/block/sda/queue/scheduler文件来临时修改调度器类型,永久修改可以参考如下命令 grubby --grub --update-kernel=ALL --args="elevator=deadline" deadline使用了3个队列,”standerd queue“中按照block号排序,”read FIFO”和“write FIFO“则按照request请求的顺序添加,read FIFO的超时时间为500ms,write FIFO的超时时间为5s。系统会按照顺序处理standerd queue中的请求,当read FIFO或write FIFO超时后会切换到对应的FIFO处理request。这种处理方式用于防止”request starvation“,即系统可能会在某个block上处理多个request,而导致其他block上的request超时。更多详情参见Kernel Korner - I/O Schedulers,需要注意的是Anticipatory I/O Scheduler已经被废弃。 在遇到系统读写过慢时,可以采用如下步骤进行定位。(注:该系统的模拟故障由dd if=/dev/zero of=loadfile bs=1M count=5000触发):
Tasks: 77 total,2 running,1)">75 sleeping,1)">0 stopped,1)">0 zombie %Cpu(s): 0.7 us,1)">14.6 sy,1)">0.0 ni,1)">0.0 id,1)">84.7 wa,1)">0.0 hi,1)">0.0 si,1)">0.0 st KiB Mem : 1014908 total,1)">63716 free,1)">69912 used,1)">881280 buff/cache KiB Swap: 0 total,1)">0 free,1)">0 used. 779008 avail Mem
util:采集周期内用于IO操作的时间比率,该值过高直接说明IO占比过高,下面util已经升到了97.19%,IO已经很高了 await:平均每次IO请求等待时间(包括等待时间和处理时间,毫秒为单位),该值过高说明IO队列可能比较长,IO队列长度可以参考avgqu-sz(平均等待处理的IO请求队列长度) svctm:平均每次IO请求的处理时间(毫秒为单位),正常情况下该值与await相差不大,差距越大,越说明IO过高。 IO有读写之分,如下例中明显写操作IO影响了性能,且设备为磁盘sda(iostat -x -k -d 1 2) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 1.04 227.08 4.17 108850.00 954.34 124.40 1056.26 87.00 1060.71 4.26 97.19
Total DISK READ : 0.00 B/s | Total DISK WRITE : 403.22 M/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 411.90 M/s PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 15162 be/4 root 0.00 B/s 403.22 M/s 0.00 % 80.05 % dd if=/dev/zero... ... 使用lsof查看该进程打开的文件,可以看到/home/loadfile的大小达到了4564156416 # lsof -p 15394 lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dd 15394 root cwd DIR 253,1)">0 63 50444361 /home dd 15394 root rtd DIR 0 238 64 / dd 15394 root txt REG 0 74952 50454589 /usr/bin/dd dd 15394 root mem REG 0 106075056 17088179 /usr/lib/locale/locale-archive dd 0 2151672 162056 /usr/lib64/libc-2.17.so dd 0 163400 162049 /usr/lib64/ld-15394 root 0r CHR 1,1)">5 0t0 6479 /dev/zero dd 15394 root 1w REG 0 4564156416 52606435 /home/loadfile dd 15394 root 2u CHR 136,1)">0 0t0 3 /dev/pts/0 确定/home/loadfile文件的挂载路径,为根路径 # df /home/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/centos-root 17811456 10109916 7701540 57% / 查看根路径挂载的磁盘(本例中为一块磁盘,可以忽略该步骤),为发生IO性能问题的磁盘sda,到此基本可以确认是因为进程15162引发了IO问题。注:可以使用如“time dd if=/dev/zero bs=1M count=2048 of=direct_2G”命令测试磁盘性能 # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 20G disk ├─sda1 1 0 1G 0 part /boot └─sda2 2 0 19G part ├─centos-root 253:0 17G 0 lvm / └─centos-swap 0 2G lvm [SWAP] ? linux 大页 Linux采用了通用的分页模型,用以减少进程使用的页表以及增加对内存的索引。在Linux-2.6.10版本中,Linux采用了三级分页模型. 而从2.6.11开始普遍采用了四级分页模型,32位系统中取消了PUD和PMD,为二级分页模型。注:每个进程都有其自身的页面目录PGD
下面是一个线性地址包含的各字段以及各字段的用途 注:CR3中含有页目录表物理内存基地址,因此该寄存器也被称为页目录基地址寄存器PDBR(Page-Directory Base address Register),用于定位进程PGD 对于32位系统来说,如果采用4K的分页大小,每个PGD含1024个目录,每个目录含1024个PT,每个PT可寻址4K物理内存,总计4G。从上述可以看出,当进程需要访问实际物理内存时需要经过多级页才行,为了增加地址访问效率,linux使用了一种页缓存,TLB(translation lookaside buffer)。当需要访问物理地址时会首先从TLB中寻找,若找到则称为TLB hit,否则称为TLB miss。 ? 这篇文章描述了使用系统默认4k分页下出现的性能问题,总结下来就是:64位系统下,一个进程访问的内存空间变大时,其PGD里面的页表项也会变大,如一个进程访问一个12G内存时,其页表需要24M,当300个进程同时需要访问这12G内存时,总的页表达到了7200MB,这么大的页表不仅占用大量内存空间,页增加了地址访问的负担(TLB miss也会大大增加)。解决办法是使用大页内存,通过增加单个分页大小,进而减少总体需要的分页的数目(同时也提升了TLB hit的几率) 可以看出,大页内存一般用于64位系统或32位系统启用了PAE(内存地址扩展)的情况。页表的使用情况可以参见/proc/meminfo中的PageTables字段 下面描述来自这里
? TIPS:
? 参考: https://blog.csdn.net/gzh0222/article/details/8666657 https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html https://zorro.gitbooks.io/poor-zorro-s-linux-book/content/linuxde-io-diao-du.html http://bencane.com/2012/08/06/troubleshooting-high-io-wait-in-linux/ https://www.ibm.com/developerworks/cn/linux/l-memmod/index.html https://www.ibm.com/developerworks/cn/linux/l-cn-hugetlb/ https://github.com/gatieme/LDD-LinuxDeviceDrivers/blob/master/study/kernel/02-memory/02-pagetable/01-develop/README.md (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |