II17OS优化(2)
虚拟化对于内存子系统的虚拟是很麻烦的,原因:虚拟化环境中,进程地址PA-->虚拟机内存地址HA-->物理内存地址MA,虚拟机上的进程PA转换的结果在HA上,HA还要转换为MA,CPU找的是物理内存地址MA,这种效率很低
虚拟机的OS称为guest OS,当前的物理主机称宿主机
宿主机要监控着HA到MA的转换,一旦发现虚拟机的HA要执行特权指令了,要完成HA到MA的转换,若直接从PA-->MA则要好很多,若硬件不支持的话将无法完成直接转换,必须二次转换才可,现在很多支持硬件虚拟化的CPU都能够提供影子页表shadow PT,page table,它能够在原有的MMU的旁边再提供一个虚拟MMU(假的缓存的MMU芯片),让guest OS转换时到真的MMU上去,而宿主机的OS负责自动在背后同步就完成从HA-->MA的转换,由此通知CPU直接一步一次性完成从PA-->MA的转换,地址翻译(或叫虚拟内存)是X86平台最难虚拟化的组件,除此之外只能完全进行模拟
系统优化的三个层次:守护进程;OS内核;硬件
硬件(硬件性能足够好,其上的所有参数都不用调,足以扛得下所有应用,选择与业务合适的硬件,符合业务处理需求的(分析业务本身是CPU密集型还是IO密集型,对内存的资源需要多少,对CPU的计算量要多大等),有了这样的直观认识才会知道某个服务在什么硬件上比较合适,硬件调优就是硬件选型,如cache server、mysql server等环境)
OS内核(对整个底层硬件管理的最根本所在,内核功能要能够有效使用这些硬件,如调整内存参数、进程的优先级等,无非内核在使用底层硬件资源上得到更有效的配置,从而加速内核在使用硬件计算资源方面的能力)
守护进程(每种守护进程的调整各不相同,如nginx(nginx自身的参数指标,如CPU绑定、开启的线程数、使用多少缓存等),而网络方面、CPU绑定(nginx可自行绑定)、IPC调整等归根结底还是系统内核方面的调整;而对于某种特定复杂的服务,如mysql,它自身服务参数的调整(服务级别调整)影响较大,如索引的设计、storage engine的选择等;而对于简单的服务来说在服务级别调整意义并不大,如httpd无非是选择一个高性能的MPM模块,关掉某些不必要的功能,打开压缩等,压缩未必是调优,它能优化带宽的使用,但会增加CPU的负荷,没有放之四海而皆准的方法,最重要的还是核心的基本原理)
观察系统性能指标有:内存使用、进程对CPU使用、CPU的利用率、CPU队列、网络缓冲区是否够用、线程重用、会话重用等
通过系统指标工具观察,发现某些指标不符合需要,如内存空间(物理内存、交换内存),物理内存没用完就大量使用交换内存了,通过本篇内存子系统优化即可解决
关键:
硬件选型
内核自身的调优(/proc和/sys,通过虚拟FS来同内核打交道,调整其工作参数)
应用服务级别(对于一般的服务,无非是服务如何使用系统资源,如web server的应用,通过观察性能指标,能分析出对哪些参数进行调整,在某些应用上关掉不必要的功能;对于复杂的服务如数据库,通过服务自身参数在某些特定条件下调整)
进程管理(在CPU时间片上实现)
内存调优(最复杂,原理上最需要基本功)
IO调优(尤其磁盘IO)
FS调优(与IO有关,在同样的磁盘IO下,不同的FS在某些应用上的性能表现不同)
网络子系统调优
注:CPU、memory、I/O、FS、networking;memory中capacity tuning包括(怎么使用交换内存、什么时候启动pdflush、如何调整大内存页的个数,例如overcommit_memrory=0|1|2,overcommit_ratio默认值50)
RHCA中专门的调优RH442一书
思路:
观察系统性能指标,查看哪些是bottleneck
使用相关参数对bottleneck调优,反复、全方位多角度的分析,一个一个参数调整或结合不同的参数调整
注:有时明确观察到的是CPU利用率过高,但最后发现不是CPU问题,CPU被大量用作IO上了
redhat官方称调优是black art
redhat enterprise linux6 performance工具有:
SystemTap(涉及到system编程,类似strace观察系统上各个模块的运作方式,查看系统上的每个system call,内核与进程交互时的活动状态)
OProfile(评估OS性能)
Valgrind(强大的内存泄露探测工具,程序员在编程完后评估自己程序是否有内存泄露、对于缓存的使用率等各方面的评估工具,评估CPU缓存命中、应用程序内存泄露、应用程序对缓存的利用率等)
Perf(调优工具,相较于以上三个要简单些)
虚拟内存管理virtual memory manager
如下图:在32bitOS上最多可用内存为2^32(4G),这4G分为1G的内核空间和3G的用户空间,在1G的内核空间中,有16M用来DMA(direct memeory access),这个区域包括pages,从16M-896M这800M空间是内核使用的,还有128M是用来做映射的(页表的虚拟地址和物理地址的映射关系);对于64bitOS,有1G是用来做DMA的,其它的都是实际的可用的地址空间,所以在服务器上直接使用64bitOS
1、TLB(translation lookaside buffer)传输后备缓冲器是一个内存管理单元MMU(memory management unit),用于改进虚拟地址到物理地址转换进度的缓存,TLB里面存放的是一些页表文件
TLB与CPU的L1、L2缓存类似,TLB缓存页表数据,CPU的一二级缓存的是实际数据;X86体系的系统内存里存放了两级页表,第一级页表称为页目录,第二级称为页表;若TLB中正好存放着所需的页表,则称TLB Hit,若TLB中没有所需的页表,则称TLB Miss
内存优化最主要的一点就是提升TLB的性能,使用hugetable page(大表页),要启用hugetlbfs(类似上一篇末cpuset文件系统),它能够实现使用多种不同的页面大小,可使用一部分正常的4K页面,也可使用一部分hugepages大页面
[root@node1 ~]# cat /proc/meminfo | grep -i HugePage(查看HugePage是否启用)
HugePages_Total: 0(0表示未启用)
HugePages_Free: 0
HugePages_Rsvd: 0
Hugepagesize: 4096 kB(32bitOS正常页面4K,大页面4M;64bitOS,大页面2M)
improving TLB performance:
[root@node1 ~]# vim /etc/sysctl.conf(在此文件中添加一行,也可通过内核参数hugepages=NUM设定)
nr_hugepages = NUM
当创建出大页面后,可指定被某些应用程序所使用;也可将hugepage当FS(hugetlbfs)直接使用(要挂载至某个目录下当作FS直接用,实现文件复制、删除、修改等),重启后会消失,通常将临时文件这样用
configure hugetlbfs if needed by application:
[root@node1 ~]# mkdir /hugepages
[root@node1 ~]# mount -t hugetlbfs none /hugepages/(为某个应用程序明确指明要使用hugepages才要挂载,有些应用程序如mysql会自动使用hugepages不必非得挂载FS)
[root@node1 ~]# ls /hugepages
[root@node1 ~]# dd if=/dev/zero of=/hugepages/a.txt bs=1M count=5
dd: writing `/hugepages/a.txt': Invalidargument
1+0 records in
0+0 records out
0 bytes (0 B) copied, 0.00205759 seconds,0.0 kB/s
[root@node1 ~]# ll /hugepages(注意文件大小为0,使用的是内存空间)
total 0
-rw-r--r-- 1 root root 0 Dec 21 21:28 a.txt
[root@node1 ~]# umount /hugepages
注:innodb_buffer_pool_size这个空间是让mysql的innodbstorage engine缓存数据、索引,通常特别大,若内存10G给它6G都不过分,若这6G空间被它反复拿来申请使用,若仍用4K的一般页面,性能效率就太低了,这种情形下使用hugepages可有效提高其性能(配置innodb可使用大页面,只需指定有大页面,不必挂载)
viewing system call:
某个应用程序在运行时需要操作硬件,通过system call的方式,必须由内核完成应用程序申请的特权功能
[root@node1 ~]# man strace(trace systemcalls and signals)
#strace -p PID(观察进程如何运行,执行了哪些system call)
#strace COMMAND(查看命令的system call)
#strace -o FILE -p PID(将追踪结果保存至文件中,供分析用)
#strace -c -p PID
#strace -c COMMAND
例:
[root@node1 ~]# ps -C httpd(查看某进程的PID号)
[root@node1 ~]# ab -n 100000 -c 100 http://127.0.0.1/index.html
[root@node1 ~]# strace -p 18567(该进程接收了请求,用户请求的是页面文件,页面文件中disk上,产生system call加载硬盘中的页面文件,()内都是system call)
……
read(16, "GET /index.htmlHTTP/1.0\r\nUser-A"..., 8000) = 94
gettimeofday({1450706277, 640065}, NULL) =0
stat64("/var/www/html/index.html",{st_mode=S_IFREG|0644, st_size=26, ...}) = 0
open("/var/www/html/index.html",O_RDONLY|O_LARGEFILE) = 17
mmap2(NULL, 26, PROT_READ, MAP_SHARED, 17,0) = 0xb7f47000
writev(16, [{"HTTP/1.1 200 OK\r\nDate:Mon, 21 D"..., 261}, {"the server is maintaining\n", 26}], 2) =287
munmap(0xb7f47000, 26) = 0
write(11, "127.0.0.1 - -[21/Dec/2015:21:57"..., 106) = 106
shutdown(16, 1 /* send */) = 0
……
[root@node1 ~]# stracecat /etc/fstab(execve()运行命令,open()打开一个文件,fstat()查看权限相关信息,read()读取文件内容,write()往屏幕上写)
[root@node1 ~]#strace -c cat /etc/fstab(Count time, calls, and errors for each system call andreport a summary on program exit,追踪整体结果,将汇总信息显示出来,可分析某程序执行的大量system call时间都消耗在什么地方了,如在LAMP架构中php以模块方式嵌入在httpd进程中发现httpd响应慢,可找出慢的主要原因)
……
% time seconds usecs/call calls errors syscall
------ ----------- ----------- ------------------ ----------------
nan 0.000000 0 3 read
nan 0.000000 0 1 write
nan 0.000000 0 4 open
nan 0.000000 0 5 close
nan 0.000000 0 1 execve
nan 0.000000 0 1 1 access
nan 0.000000 0 3 brk
nan 0.000000 0 1 munmap
nan 0.000000 0 3 mprotect
nan 0.000000 0 7 mmap2
nan 0.000000 0 5 fstat64
nan 0.000000 0 1 set_thread_area
------ ----------- ----------- ------------------ ----------------
100.00 0.000000 35 1 total
2、
strategies for using memory:
reduce overhead for tiny memory objects尽可能降低微小内存对象的开销(slab cache,slab allocate分配的都是用来存储元数据的tiny memory object,叫小内存数据结构,这些小内存数据结构会被频繁的创建和撤销,因此使用slab)
slab使用的内存策略:
the slab memory cache contains pre-allocated memory pools that the kernel pulls memory from when it needsspace to store various types of data structures
先申请几个内存页如kmem_cache,将内存页按类型(各种规格)划分好,分好后是slab页面,在每个页面上放一堆的object,为提高效率会事先划分好多个不同规格的页面,不管某个规格用不用都事先划分好,kmem_cache里包含很多页,分成三类如slabs_full、slabs_partial、slabs_empty,使用完一个再使用另外一个,slabs_partial正在使用中,已使用的不管,未使用的自上而下排,page中可存储object
注:slabs_full(已全部使用的slab缓存),slabs_partial(仅部分使用的slab缓存),slabs_empty(空间未使用的slab缓存)
slab用来实现小对象的快速分配和回收,使用时预先分配好,不够用再申请新的,如果某个内存对象被删除了,而它所使用的空间只是被腾空而不会删除这个空间
reduce or defer service time for slower subsystems降低或延迟慢速子系统的服务时间,整个系统,整个系统IO慢,通过提供buffer cache将数据从外围设备上加载并缓存在内存中,缩减方法:提供buffer cache):
filesystem metadata(buffer cache也叫slab cache,实际slab cache就在buffer cache中,FS的元数据在buffer上,全称buffer cache,还可用来缓存写操作)
disk IO(page cache,数据是用page cache来缓存的,元数据是用buffer cache缓存的)
interprocess communications(shared memory,shm,进程间通信使用共享内存完成)
network IO(buffer cache、arp cache、connectiontracking,网络IO借助buffer cache、arp cache、连接追踪等功能来提升性能,每个用户会话建立都要占据内存空间,实现将用户的会话存储下来并进行追踪)
总结:
(1) 降低微型内存对象的系统开销(使用slab)
(2) 缩减慢速子系统的服务时间(使用buffer cache缓存文件的元数据;使用page cache缓存disk IO文件数据;使用shm提升进程间通信的效率;使用buffer cache、arp cache、connection tracking来提升网络IO性能)
注:[root@node1 ~]# cd /proc/sys/vm
[root@node1 vm]# ls
block_dump drop_caches max_reclaims_in_progress overcommit_ratio topdown_allocate_fast
dirty_background_bytes flush_mmap_pages max_writeback_pages pagecache vdso_enabled
dirty_background_ratio hugetlb_shm_group min_free_kbytes page-cluster vfs_cache_pressure
dirty_bytes laptop_mode mmap_min_addr panic_on_oom vm_devzero_optimized
dirty_expire_centisecs legacy_va_layout nr_hugepages percpu_pagelist_fraction
dirty_ratio lowmem_reserve_ratio nr_pdflush_threads swappiness
dirty_writeback_centisecs max_map_count overcommit_memory swap_token_timeout
tuning page allocation(调整页面分配):
vm.min_free_kbytes(最小空闲Kb数,内存有物理内存和交换内存,交换内存可当内存来使用,当前主机会运行很多进程,每个进程运行时可能会打开文件申请新的内存空间使用,同时运行的多个进程,当有进程又要申请内存空间时,若内存空间不够用,当内存耗尽系统会崩溃的,因此无论如何不能让内存耗尽,而且内存空间太少也不能保证多个进程正常使用,所以要将某些物理内存页交换到交换内存中,此项就是定义物理内存最少空闲多少空间,这样物理内存始终不会占满,已预留出了最小空间,当某进程又要申请空间但内存占满,这时就要将某些占用内存最多的进程给交换到交换内存中了,绝大多数场景都不需调整此参数,仅特殊场景下要调,如磁盘太慢、CPU性能太差时,可将此项调小一点,因为这段预留的空间将无法被其它进程使用,必须要空闲出来一些)
[root@node1 vm]# cat min_free_kbytes
2048
tuning overcommit(调整内存过量使用,常用,尤其在虚拟化环境中尤其有用):
vm.overcommit_memory =0|1|2
0(heuristic overcommit,启发式过量,由OS内核自己决定要不要过量什么时候过量使用,什么时候使用交换内存及使用多少交换内存)
1(always overcommit,总是过量使用,在任何场景都用交换内存;此项在DB server上尽可能不要使用,swap太慢了;在有些场景如hadoop下这是个批处理系统,对real time实时的要求不高,需要大量内存用来计算,使用此项)
2(commit all RAM plusa percentage of swap(may be>100),所有物理内存加一部分swap内存)
注:主机上运行多个虚拟机,每个虚拟机分配的有虚拟CPU(按时间切片虚拟),如宿主机1颗CPU4核心,在此宿主上安装了4个虚拟机,给每个虚拟机分配1颗CPU2核心,这就共8核了,过量使用;若宿主机上8G内存,若给这4个虚拟机每个分4G的内存会分配不出去,会提示没有更多的内存空间可用,在物理机的基础上过量使用,CPU可以多虚拟出几个(按时间虚拟),内存则不行(是空间映射),物理内存的过量使用是以swap为前提的,可以超出物理内存一部分,在性能要求很高的场景能不使用swap则不使用
vm.overcommit_ratio(用来定义可超出物理内存的比例,默认值50,仅在vm.overcommit_memory=2时使用,注意确保此物理内存空间*此比例不能超出swap内存空间的实际大小,否则会内存溢出out of memory,OOM很严重,内核要执行一些管理操作将无空间可用,这时内核会找一些使用内存空间比较大的进程不管是谁也不管重不重要将其干掉,内核中有OOM killer,可自定义一旦有OOM将杀死哪些进程,根据进程的评分,每个进程都有评分,得分高的将优先被杀)(/proc/PID/oom_score,/proc/PID/oom_adj,/proc/PID/oom_score_adj可调整分数)
[root@node1 ~]# cat /proc/sys/vm/overcommit_memory
0
[root@node1 ~]# cat /proc/sys/vm/overcommit_ratio
50
[root@node1 ~]# cat /proc/7359/oom_score
1
[root@node1 ~]# cat /proc/7359/oom_adj
0
[root@node1 ~]# cat /proc/7359/oom_score_adj
0
slab cache(调大slab cache可提升CPU在访问内存小对象时的性能):
[root@node1 vm]# cat /proc/slabinfo
slabinfo - version: 2.1
# name <active_objs><num_objs> <objsize> <objperslab> <pagesperslab> :tunables <limit> <batchcount> <sharedfactor> : slabdata<active_slabs> <num_slabs> <sharedavail>
ip_vs_conn 0 0 128 30 1 : tunables 120 60 8 : slabdata 0 0 0
rpc_buffers 8 8 2048 2 1 : tunables 24 12 8 : slabdata 4 4 0
……
[root@node1 vm]# cat /proc/slabinfo | grep -E "(dentry|ext3)"(dentry和inode cache)
ext3_inode_cache 2999 5432 492 8 1 : tunables 54 27 8 : slabdata 679 679 0
ext3_xattr 729 1092 48 78 1 : tunables 120 60 8 : slabdata 14 14 0
dentry_cache 8442 11165 136 29 1 : tunables 120 60 8 : slabdata 385 385 0
[root@node1 vm]# man slabtop(displaykernel slab cache information in real time)
[root@node1 vm]#slabtop(随时监控着系统上的slab对象,在某些特定场景,调整slab对象的参数以使得有足够的不同类型的slab空间可用,Active活动对象,当使用百分比过高时再次打开类似对象就要清除一些缓存,腾出空间,每种类型的数目总体是有限定的,用量很大的dentry_cache、ext3_inode_cache,一般FS和目录的用量都是很大的)
Active / Total Objects (% used) : 317793 / 345656 (91.9%)
Active / Total Slabs (% used) : 5069 / 5069 (100.0%)
Active / Total Caches (% used) : 103 / 153 (67.3%)
Active / Total Size (% used) : 15928.85K / 18870.70K (84.4%)
Minimum / Average / Maximum Object : 0.01K /0.05K / 128.00K
OBJSACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
144130 144056 99% 0.02K 710 203 2840K avtab_node
101700 100590 98% 0.03K 900 113 3600K size-32
注:dentry(通过目录可找到文件,路径映射关系,每打开一个文件路径映射关系都缓存到slab object中,否则每次打开都很慢)
[root@node1 vm]#vmstat �m(Report virtual memory statistics,The -m displaysslabinfo)
Cache Num Total Size Pages
ip_vs_conn 0 0 128 30
rpc_buffers 8 8 2048 2
rpc_tasks 8 20 192 20
rpc_inode_cache 6 9 448 9
ip_fib_alias 10 113 32 113
ip_fib_hash 10 113 32 113
tuning a particular slab cache:
#echo “cache_name limit batchcount sharedfactor” > /proc/slabinfo(可被CPU缓存的最多对象条目,batchcount当CPU缓存为空时一次性传到CPU缓存对象的个数,sharedfactor在SMP架构各CPU间共享的slab缓存条目)
[root@node1 vm]# echo "ext3_inode_cache 108 54 8" > /proc/slabinfo
[root@node1 vm]# cat /proc/slabinfo | grep ext3
ext3_inode_cache 2999 5432 492 8 1 : tunables 108 54 8 : slabdata 679 679 0
ext3_xattr 729 1092 48 78 1 : tunables 120 60 8 : slabdata 14 14 0
arp cache(
默认arp的缓存在/proc/net/arp文件中,默认缓存512个条目(soft limit),最多可缓存1024(hard limit),超出512个后只能缓存有限的时间(5s,默认是5min),若缓存数目超过硬限制,内核中有GC,garbage collection会清理一些过时的stale和废旧的条目older entries,arp缓存的条目默认只5min,若处在一个非常大的网络中应将此项调大,否则缓存的条目会被频繁刷新,C网默认253个主机,若处在网络中的主机不多,此项一般都不需调)
查看缓存列表条目:
[root@node1 vm]#cat /proc/net/arp
IP address HW type Flags HW address Mask Device
192.168.41.1 0x1 0x2 00:50:56:C0:00:08 * eth0
[root@node1 vm]# ipneighbor list
192.168.41.1 dev eth0 lladdr00:50:56:c0:00:08 REACHABLE
[root@node1 vm]# ipneighbor flush dev eth0(flush cache清空某个设备上的所有缓存条目)
[root@node1 vm]# ipneighbor flush
Flush requires arguments.
/proc/sys/net/ipv4/neigh/default/下有thresh{1,2,3}三个预值,默认分别为128、512、1024,
net.ipv4.neigh.default.gc_thresh1(默认128个条目,gc不管)
net.ipv4.neigh.default.gc_thresh2(默认512个条目,softupper limit)
net.ipv4.neigh.default.gc_thresh3(默认1024个条目,hardupper limit)
net.ipv4.neigh.default.gc_interval(gc间隔时间,gcfrequency in seconds)
注:超过128个没到512个要清理过期条目;超过512个的条目缓存时长仅5s
[root@node1 vm]# cd /proc/sys/net/ipv4/neigh/default/
[root@node1 default]# cat gc_thresh1
128
[root@node1 default]# cat gc_thresh2
512
[root@node1 default]# cat gc_thresh3
1024
[root@node1 default]# cat gc_interval
30
page cache(主要目的加速读操作,a large percentage of paging activity is due to I/O,file reads:each pageof file read from disk into memory,these pages form thepage cache):
读进的文件若修改,之后要清写到磁盘上,要将page cache中的内容同步到磁盘,同步有可能要借助buffer完成,有时直接将page cache的内容写到磁盘,并没严格限定写必须要使用buffer,读必须用cache
page cache is always checked for IO requests:
directory reads
reading and writing regular files(普通文件的r和w,这里的w是指在page cache中修改,修改完后用回写策略过一段时间才同步到磁盘上,同步到磁盘上的过程是清写)
reading and writing via block devicefiles,DISK IO(r和w通过块设备的DISK IO实现)
accessing memory mapped files,mmap(为加速使用内存映射)
accessing swapped out pages(有时过量内存使用会将pages交换到交换内存中)
tuning page cache:
vm.lowmem_reserve_ratio(在低端内存中为pagecache预留空间的比例,低端内存ZONE_DMA和ZONE_NORMAL那段,在64bitOS上此参数不用调)
vm.vfs_cache_pressure(虚拟FS的缓存pressure,内核回收dentries和inodes的缓存对象,为加速访问文件这些缓存空间不应该回收,默认值100,0(不回收dentries和inodes),1-99(倾向于不回收),100(倾向于page cache和swap cache相同时,试图回收dentries和inodes),100以上(倾向于回收dentries和inodes))
vm.page-cluster(页簇,物理内存中一次拿多少个页面到交换内存中,1表示2^1,2表示2^2,默认是3,8个,一般系统若要大量使用交换分区时调大此值才有意义,一般最大调为4,可获得稍微性能提升,不要再大于4,在云计算场景和虚拟机环境常用此参数(在一个物理机上运行多个虚拟机,虚拟机的内存很有可能超出物理内存,要频繁使用交换内存))
vm.zone_reclaim_mode(此项用的很少,现在都用64bitOS考虑区域的场景很少见,倾向于回收哪个区域的模型,1(表示区域回收功能开启,由内核自行决定如何回收),2(回收写操作产生的脏页,脏页同步到磁盘即回收回来),4(回收swaps pages)
[root@node1 ~]# cat /proc/sys/vm/lowmem_reserve_ratio
256 256 32
[root@node1 ~]# cat /proc/sys/vm/vfs_cache_pressure
100
[root@node1 ~]# cat /proc/sys/vm/page-cluster
3
anonymous pages:
Anonymous pages=RSS-shared(实际内存集-共享内存集),匿名页占据的空间不能被交换出
匿名页中通常不是文件内容(文件打开后放在page cache中),包含数据有:
program data-arrays,heap allocations,etc(程序自身产生的数据)
anonymous memory regions(匿名内存区域,有些区域无法全名不方便引用)
dirty memory mapped process private pages(脏内存页面映射为进程私有页面)
IPC shared memory region pages(进程间通信的内存区域页面)
注:IPC有三种:基于信号semaphores方式,基于共享内存shm(仅两个进程通信时才使用此种方式,进程间通信也有参数需要调),基于消息队列message queues)
[root@node1 ~]# grep Anon /proc/meminfo
AnonPages: 17496 kB
AnonHugePages: 0 kB
[root@node1 ~]# cat /proc/7359/statm
43371 598 158 84 0 403 0
IPC调优(shared memory、messages、semaphores):
[root@node1 ~]# man ipc(System V IPCsystem calls)
[root@node1 ~]# man ipcmk(createvarious ipc resources)
[root@node1 ~]# man ipcrm(remove amessage queue, semaphore set or shared memory id,万一某个IPC睡眠了,唤醒不了卡死了,使用这个命令移除)
[root@node1 ~]# man ipcs(provideinformation on ipc facilities)
[root@node1 ~]# ipcs -h
ipcs provides information on ipc facilitiesfor which you have read access.
Resource Specification:
-m: shared_mem
-q: messages
-s: semaphores
-a: all (default)
Output Format:
-t: time
-p: pid
-c: creator
-l: limits
-u: summary
-i id [-s -q -m] : details on resourceidentified by id
usage : ipcs -asmq -tclup
ipcs[-s -m -q] -i id
ipcs-h for help.
[root@node1 ~]#ipcs �l(-a,all默认,-s,shm,-q,messages,-s,semaphores)
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 67108864
max total shared memory (kbytes) =17179869184
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
------ Messages: Limits --------
max queues system wide = 454
max size of message (bytes) = 65536
default max size of queue (bytes) = 65536
关于shm:
kernel.shmmni(在全系统范围内最大允许使用多少个共享内存段,经常用,尤其在数据库server上,default4096,单位byte,定义系统级别所允许使用的共享内存段上限,有时有点少)
kernel.shmall(系统级别一次性可使用的最大共享内存页面数,能够为共享内存分配使用的最大页面数,默认2097152,单位byte,this should be at least kernel.shmmax/page_size)
kernel.shmmax(单个共享内存段的上限,以字节为单位创建)
关于messages:
kernel.msgmni(系统级别,消息队列个数的上限,默认16)
kernel.msgmnb(单个消息队列的上限,单位byte,默认16384)
kernel.msgmax(单个消息大小的上限,单位byte,默认8192)
注:通过#ipcs �p PID查看某一个应用的shm和messages的大小,一旦发现不够用将其调大,shm和messages一般都是将其调大
[root@node1 ~]# cat /proc/sys/kernel/shmmni
4096
[root@node1 ~]# cat /proc/sys/kernel/shmall
4294967296
[root@node1 ~]# cat /proc/sys/kernel/shmmax
68719476736
[root@node1 ~]# cat /proc/sys/kernel/msgmni
454
[root@node1 ~]# cat /proc/sys/kernel/msgmnb
65536
[root@node1 ~]# cat /proc/sys/kernel/msgmax
65536
[root@node1 ~]# free �m(Display amount of free and used memory in the system,-m,megabytes)
total used free shared buffers cached
Mem: 230 172 58 0 15 86
-/+ buffers/cache: 70 160
Swap: 3999 11 3988
[root@node1 ~]# cat /proc/vmstat(page tables)
nr_free_pages 14864
nr_inactive_anon 1870
nr_active_anon 1384
nr_inactive_file 13112
nr_active_file 12958
nr_unevictable 0
nr_mlock 0
nr_anon_pages 2975
nr_mapped 2075
nr_file_pages 26729
[root@node1 ~]# cat /proc/meminfo(systemmemory,total physical memory,memory being used by caches,active(in use),inactive)
MemTotal: 236380 kB
MemFree: 59508 kB
Buffers: 15856 kB
Cached: 88532 kB
SwapCached: 2536 kB
Active: 57368 kB
Inactive: 59932 kB
Active(anon): 5536 kB
Inactive(anon): 7480 kB
[root@node1 ~]# vmstat �s(summary,或使用#sar �r 110,report memory and swap space utilization statistics)
236380 total memory
176932 used memory
57368 active memory
59976 inactive memory
59448 free memory
15888 buffer memory
88532 swap cache
4095992 total swap
11616 used swap
4084376 free swap
9201 non-nice user cpu ticks
0 nice user cpu ticks
14459 system cpu ticks
6857440 idle cpu ticks
18395 IO-wait cpu ticks
40 IRQ cpu ticks
3869 softirq cpu ticks
0 stolen cpu ticks
581699 pages paged in
188630 pages paged out
19041 pages swapped in
20108 pages swapped out
1029952 interrupts
791138 CPU context switches
1452896188 boot time
8230 forks
[root@node1 ~]# vmstat �a(switchdisplays active/inactive memory)
procs -----------memory---------- ---swap-------io---- --system-- -----cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
0 0 11616 59216 60048 57420 1 1 8 3 15 11 0 099 0 0
pdflush清写内存的dirty page到磁盘上,默认最少2个pdflush线程,一般1个磁盘要有1个pdflush线程
vm.nr_pdflush_threads(显示当前pdflush线程的个数,redhat6会自动管理pdflush的线程数)
[root@node1 ~]# cat/proc/sys/vm/nr_pdflush_threads
0
tuning pdflush:
vm.dirty_background_ratio(脏页占总内存多大比例启用pdflush开始清写,可理解为是触发条件)
vm.dirty_ratio(单个进程的脏页占总内存多大比例启用pdflush开始清写)
vm.dirty_bytes(一般都用ratio来控制,很少用bytes控制)
vm.dirty_expire_centisecs(每隔多长时间启用pdflush一次,单位百分之一秒,0表示禁止)
vm.dirty_writeback_centisecs(已很长时间的脏页启用pdflush清写到磁盘)
[root@node1 ~]# cat /proc/sys/vm/dirty_background_ratio
10
[root@node1 ~]# cat /proc/sys/vm/dirty_ratio
20
[root@node1 ~]# cat /proc/sys/vm/dirty_bytes
0
[root@node1 ~]# cat /proc/sys/vm/dirty_expire_centisecs
3000
[root@node1 ~]# cat /proc/sys/vm/dirty_writeback_centisecs
500
reclaiming clean pages(回收干净页):
[root@node1 ~]# sync
[root@node1 ~]# sync
[root@node1 ~]# echo s > /proc/sysrq-trigger(手动清写脏缓冲和缓存,清写完后就回收了,/proc/sysrq-trigger系统级别资源管理的触发器)
[root@node1 ~]# free
total used free shared buffers cached
Mem: 236380 80300 156080 0 108 8620
-/+ buffers/cache: 71572 164808
Swap: 4095992 11616 4084376
[root@node1 ~]# sync
[root@node1 ~]# sync
[root@node1 ~]# echo 1 > /proc/sys/vm/drop_caches(1,to free pagecache;2,to free dentries and inodes;3,to free pagecache denties and inodes)
[root@node1 ~]# free(上步只释放了pagecache,在cache中仍有内容与slaballocator有关)
total used free shared buffers cached
Mem: 236380 80300 156080 0 92 8616
-/+ buffers/cache: 71592 164788
Swap: 4095992 11616 4084376
out of memory killer:
一旦内存耗尽会启动OOM killer,实现把非常消耗内存的进程杀死,以腾出内存空间
/proc/PID/oom_score(谁的分数高,谁就优先被杀,分数范围-16-17,此分数是参照/proc/PID/oom_adj内核自动计算得来;在ZONE_NORMAL区域中没有可用的空间时会启动OOM killer,意味着内存耗尽)
/proc/PID/oom_adj(该值为-17-15,有效范围-16-15,用于得出oom_score的标准,该值越大oom_score就越大,越容易被杀死,-17表示该进程无论任何时候都不会被kill掉,可将重要的服务设为-17避免被kill)
32bitOS,ZONE_HIGHMEM这段是超出1G的段,而在ZONE_NORMAL段中只要内存耗尽无论ZONE_HIGHMEM中有无内容就会启动OOMkiller,64bitOS除ZONE_DMA都是ZONE_NORMAL
[root@node1 ~]# cat /proc/sys/vm/panic_on_oom(0表示启用,一旦内存耗尽就使用OOM killer,1禁用)
0
detecting memory leaks(探测内存泄露):
内存分出去了,别人不用了却释放不了,始终处于被使用状态,泄露的多了最后OOM,有些程序员写的程序有memory leaks很正常
#valgrind(此命令有很多子命令,是命令也是包名)
[root@node1 ~]# man valgrind(a suite oftools for debugging and profiling programs)
#valgrind [valgrind-options] [your-program][your-program-options]
--tool=<toolname> [default: memcheck]
Runthe Valgrind tool called toolname, e.g. Memcheck, Cachegrind, etc.
[root@node1 ~]# valgrind --tool=memcheck cat /proc/$$/maps($$表示当前进程,memcheck表示子组件名称,注意以下红色字体)
==8438== Memcheck, a memory error detector
==8438== Copyright (C) 2002-2012, and GNUGPL'd, by Julian Seward et al.
==8438== Using Valgrind-3.8.1 and LibVEX;rerun with -h for copyright info
==8438== Command: cat /proc/7919/maps
==8438==
00400000-004d4000 r-xp 00000000 fd:00137982 /bin/bash
006d3000-006dd000 rw-p 000d3000 fd:00137982 /bin/bash
006dd000-006e2000 rw-p 00000000 00:00 0
……
7fce2cff7000-7fce2cff8000 rw-p 0000000000:00 0
7fffe97f7000-7fffe980c000 rw-p 0000000000:00 0 [stack]
7fffe991b000-7fffe991c000 r-xp 0000000000:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp00000000 00:00 0 [vsyscall]
==8438==
==8438== HEAPSUMMARY:
==8438== in use at exit: 0 bytes in 0 blocks
==8438== total heap usage: 31 allocs, 31 frees, 40,552 bytes allocated
==8438==
==8438== All heap blockswere freed -- no leaks are possible
==8438==
==8438== For counts of detected andsuppressed errors, rerun with: -v
==8438== ERROR SUMMARY: 0errors from 0 contexts (suppressed: 6 from 6)
[root@node1 ~]# watch -n 1 'ps axo pid,comm,rss,vsize | grep httpd'(若rss和vsize只增不减就很可能内存泄露,rss,resident setsize别名rsz,vsize,virtual memory size of the process in KB)
[root@node1 ~]# sar -R 1 120(-R,Report memory statistics,查看系统范围内整体内存的分配情况,若内存只往外分配没有释放,或分配的多释放的少,也意味着memory leaks,要长期观察)
what is swap:
swap out(从系统写到swap交换分区上)
swap in(从swap交换分区读数据进来)
inactive pages非活动页和anonymous pages匿名页可被swapped(通常都是inactive pages)
swap cache(从swap in读进来的页面未做修改,在多个进程访问同一页框时可避免资源竞争,多个进程可从swap cache中读一个资源)
improving swap performace:
(1)frequent small swaps,swap anonymous pages more readily(使用swap小分区,也可将anonymous pages交换出去)
注:anonymous pages(用户模式下的标准栈或使用mmap匿名映射的内存区)
(2)reduce visit count(降低或不使用swap,增大物理内存最有效,有多块磁盘划分多个swap分区)
(3)reduce service time(或不得不使用,降低服务时间,使用快速设备SSD盘,SSD用作cache server还行用做swap分区就奢侈了,或将swap分区置于硬盘最外道的分区上)
注:若有多块磁盘,使用多个交换分区(或仅一块盘就不必划分多个swap分区,除增大寻址时间并无益处),每块磁盘上都划分一个交换分区,同时将优先级调为一致,当系统往交换分区上交换数据时类似LB似的会轮流使用,这可有效降低每个分设备的访问次数,若某块磁盘较慢可将此块盘swap分区的优先级降低
tuning swappiness:
vm.swappiness(默认不交换匿名页,若要交换匿名页调整此项,调大倾向于交换,默认60,此项是个调整参数,映射到页表中的内存大小占整个内存的百分比大于等于100时就启用交换内存,对性能要求高的场景应调小此值,调大此值是让内存有更大空间可用,若内存不够用将anonymous pages交换出去可提高性能,page cache具有多次被访问的可能性)
注:% of memory mapped into page tables + vm.swappiness >=100
[root@node1 ~]# cat /proc/sys/vm/swappiness
60
tuning swap size:
up to 4*RAM(batch compute server运行科学计算的场景)
<=1G(数据库server)
>=0.5*RAM(application server)
tuning swap for think time:
vm.page_cluster(可一次性一批交换多点)
[root@node1 ~]# cat /proc/sys/vm/page-cluster
3
tuning swap visit count:
#mkswap [-L SWAP_LABEL] /PATH/TO/DEVICE
#vim /etc/fstab
/dev/sda1 swap swap pri=5 0 0
/dev/sdb1 swap swap pri=5 0 0
LABEL=testswap swap swap pri=5 0 0
/swap/swapfile1 swap swap pri=5 0 0
#swapon -a
monitoring memory usage:
(1) memroy activity:
[root@node1 ~]# vmstat -n 1 3(The -n switch causes the header to be displayed only once ratherthan periodically)
procs -----------memory---------- ---swap-------io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 11616 137804 5176 21640 1 1 7 2 14 11 0 0 99 0 0
0 0 11616 137780 5176 21668 0 0 0 0 25 24 0 0 100 0 0
0 0 11616 137780 5176 21668 0 0 0 0 20 17 0 0 100 0 0
[root@node1 ~]# sar -r 1 3(-r,Report memory utilization statistics)
Linux 2.6.32-358.el6.x86_64(node1.magedu.com) 2016年01月16日 _x86_64_ (2CPU)
17时50分47秒 kbmemfreekbmemused %memused kbbuffers kbcached kbcommit %commit
17时50分48秒 137608 98772 41.79 5192 21668 142776 3.30
17时50分49秒 137592 98788 41.79 5192 21668 142776 3.30
17时50分50秒 137592 98788 41.79 5192 21668 142776 3.30
平均时间: 137597 98783 41.79 5192 21668 142776 3.30
[root@node1 ~]# dstat 1 3
----total-cpu-usage---- -dsk/total--net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 0 99 0 0 0| 14k 4735B| 0 0 |1867B 1972B| 28 22
0 0 100 0 0 0| 0 0 | 60B 842B| 0 0 | 27 19
0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 20 17
0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 25 20
[root@node1 ~]# dstat -m 1 3
------memory-usage-----
used buff cach free
73.8M 5844k 23.6M 128M
73.8M 5844k 23.6M 128M
73.8M 5844k 23.6M 128M
73.8M 5844k 23.6M 128M
[root@node1 ~]# dstat -s 1 3
----swap---
used free
11M3989M
11M3989M
11M3989M
11M3989M
rate of change in memory:
[root@node1 ~]# sar -R 1 3
Linux 2.6.32-358.el6.x86_64(node1.magedu.com) 2016年01月16日 _x86_64_ (2CPU)
17时56分02秒 frmpg/s bufpg/s campg/s
17时56分03秒 -15.15 0.00 0.00
17时56分04秒 0.00 0.00 0.00
17时56分05秒 0.00 0.00 0.00
平均时间: -5.02 0.00 0.00
swap activity:
[root@node1 ~]# sar -w 1 3(-w,Report task creation and system switching activity)
Linux 2.6.32-358.el6.x86_64(node1.magedu.com) 2016年01月16日 _x86_64_ (2CPU)
17时56分50秒 proc/s cswch/s
17时56分51秒 0.00 19.00
17时56分52秒 0.00 24.24
17时56分53秒 0.00 20.79
平均时间: 0.00 21.33
all IO:
[root@node1 ~]# sar -B 1 3(-B,Report paging statistics)
Linux 2.6.32-358.el6.x86_64(node1.magedu.com) 2016年01月16日 _x86_64_ (2CPU)
17时58分16秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/spgscand/s pgsteal/s %vmeff
17时58分17秒 0.00 0.00 35.00 0.00 70.00 0.00 0.00 0.00 0.00
17时58分18秒 0.00 0.00 39.39 0.00 70.71 0.00 0.00 0.00 0.00
17时58分19秒 0.00 24.00 34.00 0.00 71.00 0.00 0.00 0.00 0.00
平均时间: 0.00 8.03 36.12 0.00 70.57 0.00 0.00 0.00 0.00
注:完成内存分配的申请、释放由slab allocator和buddy allocator
将线性地址映射到物理地址是MMU
pdflush会每隔一段时间清写物理内存的数据到磁盘
kswapd监控到交换内存的换进换出
注:hugepage、oom、IPC、pdflush、slab、swap
disk:
IO scheduler(/sys/<block_device>/queue/scheduler):
CFQ(complete fair queue,默认)
deadline(最后期限调度)
NOOP(no operation)
anticipatory(期望,读这个数据之后会等待几ms读后面的数据,适合顺序读写多的场景)
memory:
MMU(memory managementunit;TLB,translation lookaside buffer,缓存MMU转换的结果,使用hugetlbfs(hugepages),MMU是芯片,TLB也是内存的一缓存芯片)
vm.swappiness=#(默认60,使用交换分区的倾向性,数越小不使用,越大越倾向使用,此项是调整参数,page tables+vm.swappiness>=100)
overcommit_memory=0,1,2(生产环境中控制内存过量使用,0启发式过量,1总是过量,2所有物理内存加一部分swap内存可超出指定百分比)
overcommit_ratio(默认50,overcommit_memory=2时此项才有意义,可使用内存=swap+RAM*overcommit_ratio,举例如下)
举例:swap:4G,RAM:8G,overcommit_ratio=50,则可使用内存8G
swap:4G,RAM:4G,overcommit_ratio=50,则可使用内存6G
swap:2G,RAM:8G,overcommit_ratio=50,则可使用内存6G
一般swap是ram的一半,可保存内存充分使用,要想100%的使用物理内存,方法一:swap跟RAM一样大,vm.swappiness=0;方法二:overcommit_memory=2,overcommit_ratio=100,vm.swappiness=0
networking:
/proc/sys/net/ipv4:
tcp_mem(tcp socket缓冲大小,包括接收缓冲和发送缓冲)
tcp_rmem(接收缓冲)
tcp_wmem(发送缓冲)
tcp_fin_timeout
tcp_max_tw_buckets(保存系统处于timeout状态的连接个数,只能调大)
/proc/sys/net/core:
rmem_max
rmem_default
wmem_max
wmem_default
IPC:
shm(/proc/sys/kernel/{shmmni,shmall,shmmax})
messages(/proc/sys/kernel/{msgmni,msgmnb,msgmax}
常用命令:
top,free,iostat,sar,dstat,mpstat,iotop,vmstat,uptime,netstat,strace,lsof,blktrace,blkparse,btt,time,ss,perf,dd,iozone,io-stress,fio