Linux内存监控与调优

时间:2021-05-14 03:41:13

 

首先,内存在被使用是被分为区域的

32位系统:zone_DMA

    ・zone_NORMAL (正常内存区域 16M) 

    ・zone_RESRVED(用于高地址内存空间 896M)

    ・zone_HIGHMEM(高地址内存空间 )

 

64位系统:

    ・zone_DMA(16G)

    ・zone_DMA32(4G)

    ・zone_normal(大于4G)

内存大页 

    HugePage:大页面,在rhel 6 x64位系统上不但支持大页面而且支持使用透明大页

    THP:透明大页,简单来讲就是对匿名内存的使用,不需要用户的参与自动在背后使用大页面来管理匿名内存段

    匿名内存页:RSS - 内存段 = 匿名页

     

它支持两种内存大小:

CentOS 6.4 x86_64 : 

    单个页面大小可达到1G,在TB级的内存使用上通常有效

    小于TB级的内存,2M比较常见的

varnish是实现可以支持在内存中提供缓存的,而varnish据说跟透明大页是不兼容的,而透明大页通常情况下是系统在背后使用的,既然不兼容则需要将透明大页的功能关闭

 

查看内存大页相关信息

[root@node3 ~]# cat /proc/zoneinfo

Node 0, zone     DMA                #显示出是否使用透明大页

  pages free     3936

        min      83

        low      103

        high     124

       scanned  0

       spanned  4095

       present  3837

    nr_free_pages3936

    nr_inactive_anon0

    nr_active_anon0

   nr_inactive_file 0

    nr_active_file0

    nr_unevictable0

    nr_mlock     0

    nr_anon_pages 0

    nr_mapped    0

    nr_file_pages 0

    nr_dirty     0

    nr_writeback 0

   nr_slab_reclaimable 0

   nr_slab_unreclaimable 0

   nr_page_table_pages 0

    nr_kernel_stack0

   nr_unstable  0

    nr_bounce    0

    nr_vmscan_write0

   nr_writeback_temp 0

   nr_isolated_anon 0

   nr_isolated_file 0

    nr_shmem     0

    numa_hit     1

    numa_miss    0

    numa_foreign 0

    numa_interleave0

    numa_local   1

    numa_other   0

    nr_anon_transparent_hugepages 0             #匿名的透明矩形页有0个,0说明没有使用

 

        protection:(0, 2004, 2004, 2004)

  pagesets

    cpu: 0

             count: 0

             high:  0

             batch: 1

  vm statsthreshold: 6

    cpu: 1

             count: 0

             high:  0

             batch: 1

  vm statsthreshold: 6

    cpu: 2

             count: 0

             high:  0

             batch: 1

  vm statsthreshold: 6

    cpu: 3

             count: 0

             high:  0

             batch: 1

  vm statsthreshold: 6

 all_unreclaimable: 0

 prev_priority:     12

  start_pfn:         1

 inactive_ratio:    1

 

#以下是32位系统相关信息

Node 0, zone    DMA32

  pages free     219541

        min      11180

        low      13975

        high     16770

       scanned  0

       spanned  520189

       present  513077

    nr_free_pages219541

   nr_inactive_anon 2190

    nr_active_anon77259

   nr_inactive_file 64767

    nr_active_file70570

    nr_unevictable0

    nr_mlock     0

    nr_anon_pages27601

    nr_mapped    6761

    nr_file_pages137536

    nr_dirty     5

    nr_writeback 0

   nr_slab_reclaimable 24374

   nr_slab_unreclaimable 7081

   nr_page_table_pages 3912

    nr_kernel_stack172

   nr_unstable  0

    nr_bounce    0

    nr_vmscan_write0

   nr_writeback_temp 0

   nr_isolated_anon 0

   nr_isolated_file 0

    nr_shmem     2200

    numa_hit     40788326

    numa_miss    0

    numa_foreign 0

    numa_interleave15094

    numa_local   40788326

    numa_other   0

   nr_anon_transparent_hugepages 97           #自动启动透明大页,而一个页面的小小为2MB

        protection:(0, 0, 0, 0)

  pagesets

    cpu: 0

             count: 127

             high:  186

             batch: 31

  vm statsthreshold: 30

    cpu: 1

             count: 87

             high:  186

             batch: 31

  vm statsthreshold: 30

    cpu: 2

             count: 50

             high:  186

             batch: 31

  vm stats threshold:30

    cpu: 3

             count: 148

             high:  186

             batch: 31

  vm statsthreshold: 30

 all_unreclaimable: 0

 prev_priority:     12

  start_pfn:         4096

 inactive_ratio:    3

一个页面大小为2M,以上没有显示页面大小,所以我们要来查看另外一个文件

[root@node3 ~]# cat /proc/meminfo

MemTotal:       1922112 kB

MemFree:         893856 kB

Buffers:          77136 kB

Cached:          473116 kB

SwapCached:           0 kB

Active:          591384 kB

Inactive:        267860 kB

Active(anon):    309040 kB

Inactive(anon):    8760 kB

Active(file):    282344 kB

Inactive(file):  259100 kB

Unevictable:          0 kB

Mlocked:              0 kB

SwapTotal:      2097144 kB

SwapFree:       2097144 kB

Dirty:              104 kB

Writeback:            0 kB

AnonPages:       308996 kB

Mapped:           27052 kB

Shmem:             8800 kB

Slab:            125692 kB

SReclaimable:     97508 kB

SUnreclaim:       28184 kB

KernelStack:       1376 kB

PageTables:       15616 kB

NFS_Unstable:         0 kB

Bounce:               0 kB

WritebackTmp:         0 kB

CommitLimit:    3058200 kB

Committed_AS:   1085080 kB

VmallocTotal:  34359738367 kB

VmallocUsed:      12468 kB

VmallocChunk:  34359720976 kB

HardwareCorrupted:    0 kB

AnonHugePages:    198656 kB               #匿名的透明大页

HugePages_Total:       0                  #矩形页面的总数

HugePages_Free:        0                  #矩形页面的空闲总数

HugePages_Rsvd:        0                  #预留数

HugePages_Surp:        0

Hugepagesize:       2048 kB               #Hugepagesize为 2M ,与nr_anon_transparent_hugepages对应

DirectMap4k:       8180 kB

DirectMap2M:    2088960 kB

AnonHugePages 除以 Hugepagesize结果为 nr_anon_transparent_hugepages 的数量,如下所示

[root@node3 ~]# echo '198656/2048 ' | bc

97

 

 

查看当前主机内存空间的使用情况

・使用free -m 查看内存使用情况

free命令是最常用的,所以一般我们喜欢使用free -m 以兆为单位的显示内存使用状况

[root@node3 ~]# free -m

            total       used       free    shared    buffers     cached

Mem:         1877       1032        844          0         75        462

-/+ buffers/cache:       495       1381

Swap:        2047          0       2047

total :            物理内存总空间

Used :             已用的物理内存 

free :              剩余的物理内存

shared:            共享内存

buffers/cache:     缓存缓存

Mem :              虚拟内存

 

这里显示844的空闲内存其实并非如此,因此空闲空间加上可以清理的buffer/cache一共是1405这才是真正的空闲内存

buffer/cache的作用:访问IO设备,尤其硬盘上的文件,是非常慢的,为了加速访问使其缓存至内存中,如果后期用户对其访问则直接在内存中访问而不直接再到IO设备上检索

因此Linux在使用buffer/cache是毫不吝啬的,只要内存有空间则直接用来缓存

 

・关于 "-/+ buffers/cache"

[root@node3 ~]# free -m

            total       used       free    shared    buffers     cached

Mem:         1877       1043        683          0        178       462

-/+ buffers/cache:        471       1405

Swap:        2047          0       2047

很显然,如果已用了1877 的内存,但是大部分都被buffer和cache使用了,所以压根用的没有这么多,如果将buffer/cache减掉的话那么实际用了471的内存

 

清理buffer/cache

如果一定要清理buffer/cache的话,只需要将/proc/sys/vm/drop_caches 更改其数值即可

可以使用man proc来获取帮助进而查看其每个文件的意义

[root@node3 ~]# man proc

      /proc/sys/vm/drop_caches (since Linux 2.6.16)

             Writing to this file causes the kernel to drop clean caches, dentriesand inodes from memory, causing that

             memory to become free.

 

              Tofree pagecache, use echo 1 > /proc/sys/vm/drop_caches; to free  dentries and  inodes,  use echo  2  >

             /proc/sys/vm/drop_caches; to free pagecache, dentries and inodes, useecho 3 > /proc/sys/vm/drop_caches.

 

             Because  this  is a  non-destructive  operation and  dirty objects are notfreeable, the user should run

             sync(8) first.

以上可以得出大概信息,如果想释放pagecache,那么则执行 echo 1 > /proc/sys/vm/drop_caches

只不过buffer/cache缓存的时候被分为了两大类:

1.cache:专门用来缓存page cache 页缓存,这种缓存通常缓存的是文件数据,比如打开的文件内容

2.buffers:所缓存的是文件的元数据(inode+denty),或者通常用来缓存用户的写请求同步到硬盘上去的时候,先在内存中缓存一段时间再同步至硬盘

 

下面我们来清理buffer/cache,并观测free、buffer和cache这两个值的变化

先来查看我们当前内存资源使用情况

[root@node3 ~]# free -m

            total       used      free     shared    buffers    cached

Mem:         1877       1004       872          0         75        462

-/+ buffers/cache:       467       1409

Swap:        2047          0       2047

清理buffer/cache

[root@node3 ~]# echo 1 > /proc/sys/vm/drop_caches

[root@node3 ~]# free -m

            total       used       free    shared    buffers     cached

Mem:         1877        483       1393          0          0         26

-/+ buffers/cache:       456       1420

Swap:        2047          0       2047

所以echo 1 未必是只针对于buffer的,而cached这个值却还有数据,说明我们修改参数的时候,它的元数据在里面也存在

这时候如果我们大量去访问文件会发现buffers/cache又会增加,因为对linux而言是利用内核缓冲进行加速的

 

交换内存的优化

简单来讲,最好不要用交换内存,但是linux系统的倾向性是非常高的,在服务器上它的默认值是相当不理想的,很多默认值只是适合于交互式桌面型的

涉及参数文件:/proc/sys/vm/swappiness

于是我们man一下proc 找一下swappiness相关说明

      /proc/sys/vm/swappiness

              Thevalue in this file controls how aggressively the  kernel  will swap  memory  pages.  Higher  values

             increase agressiveness, lower values descrease aggressiveness.  The default value is 60.

我们内核有多大倾向性使用交换内存的,这个值越大,那么越倾向使用交换内存;

值越小越不倾向使用,而默认值是60,它的取值范围通常是0-100的;

[root@node3 ~]# cat /proc/sys/vm/swappiness

60

建议设置参数为0,因为0代表交换内存能不用则不用,而这正是恰恰是我们所需要的

在服务器上,尤其是物理内存缓存服务器上,比如varnish,一定强烈建议将此值改为0

 

一般而言当我们目前已经映射进页表中的内存百分比,也就是说物理内存的百分比已经被多少页表所使用了,各个进程页表映射目录里会映射出来每个线性地址到物理地址的空间,所以多个进程都启动了而且都启动映射了,那所以物理内存中的进程当中的已经被直接映射进进程页表中的空间大小的百分比 + swappiness的值 大于或等于100 的时候则启动交换内存,也就是说当我们的进程启动起来之后,会有大量的数据实现了页表映射,除了有些不能移除的之外,那这些映射页表中已经使用的映射内存空间超出了物理内存的值从而加上swapiness的值,这里swappiness是百分比) 只要大于等于100则开始启用交换存在

 

默认是60,如果这里是40%则启动交换内存,所以说不理想,如果将其调整为0,那么就表示是100%,当然是不可能到达100%,如果到达100%表示内存耗尽,如果内存耗尽对系统来将会达到另外一种状态--内存溢出(内存耗尽)

 

内存溢出/内存耗尽

在linux内核一定要有预警性的,在内存耗尽之前会将相当消耗内存的进程kill掉,一般而言linux内核会观测每个系统进程,为每个进程做标记,如发现相当占用内存的进程会将其结束,如果我们服务上运行类似于varnish的内存缓存服务的话,那么毫无疑问将结束的则是这个进程

 

所以我们要手动调整其对应的级别的,不让其内核对服务进行干扰

涉及参数文件:/proc/sysrq-trigger

调整内存相关属性:

echo f > /proc/sysrq-trigger

f表示 手动调整oom-kill 会手动启动oom-kill 会kill掉占内存级别最高的进程,当让一旦资源耗尽其也会自动启动kill的

手动指定服务级别:

echo n > /proc/pid/comm_adj

用2的N次方来估值

 

禁止oom-kill

修改内核参数 :vm.panic_on_oom = 1

意味着当系统资源耗尽的时候使系统资源崩溃

 

关注的文件:

 /proc/进程的pid /oom_score

 

需要修改的文件

#调整指数,如果不期望使某个进程级别过高,尽可能降低此值,就不会被kill

 /proc/进程的pid/comm_adj 

 

手动启动oom-kill

echo f > /proc/sysrq-trigger

 

禁用oom-kill

vm.panic_on_oom = 1

只要有交换内存可用,在交换内存中仍然有些交换内存可用,而且物理内存都是活动页的时候就不会发生oom 所以有些时候交换内存还是有用的,只要物理内存没有达到所有页面都为活动状态,那么交换内存在这种场景下还是可以起到一定额外紧急状态时的功能,所以交换内存也是必要的

 

交换内存如何设定 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

以下是IBM给出的建议,应在服务器上设置多大的交换内存设定,望各位参考:

・在执行批处理服务器计算的服务器上,尤其做科学计算的服务器上,要使用 4 x RAM 都不算过分,当然RAM也就达到64G以上,那么确实有些过分了,因需而调,一般来讲小于4G; 

・如果是数据库服务器,不管物理内存多大,那么交换内存要小于1G

   以mysql为例,在系统上运行的时候,mysql为了提高性能大多数数据都使用在内存当中,因为mysql需要大量的数据查询排序,尤其在查询排序的时候需要大量内存操作的,如果放在交换内存中的话其性能一定严重下降的,或者下降到不可接受的地步; 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

   所以,数据库服务器尽可能做到以下两点:

   1.尽可能不用交换内存

   2.让交换内存的空间足够小

・应用服务器,比如apache、tomcat之类的服务器0.5 X RAM,物理内存的一半即可,如果物理内存一共有64g 那么它的交换内存也不小,所以当内存大于4G的时候 我们需要规划一个指导线,如果物理内存大于4G的话还是依然被耗尽,那么依然需要加物理内存,因为交换内存是没有意义的,在这种情况下物理内存大于4G或者16G的话,一般交换内存分配4G左右即可;

 

不得不使用交换内存的建议

如果不得不使用交换内存,将交换内存放在越靠外的磁道上效果越好,那意味着将其放在最靠外的分区上

如果我们有多块硬盘而且没有做RAID的话,那么可以将每个硬盘最外面的分取都用于实现交换内存,假如有4块硬盘,那么将每个硬盘的最外道拿出1G来做交换内存

linux内核在使用硬盘的交换分区的时候有一特性:可以将交换分区定义优先级,我们可以让这4个的优先级一样,意味着内核以负载均衡的方式均分对交换内存的使用(负载均衡)这样就可以大大提高交换内存的使用

/dev/sda1  swap        swap   pri=5   0 0

/dev/sdb1  swap        swap   pri=5  0 0

/dev/sdc1  swap          swap   pri=5  0 0

/swaps/swapfile1         swap   pri=1   0 0  #当以上的空间全用光了再向此文件中存放数据 

当然,以上是在没有做RAID的情景下,如果有RAID0 或RAID5的话则更好 

   

手动配置大页面(Hugetable Page)

[root@node3 ~]# sysctl -a | grep hugepage
vm.nr_hugepages = 0                   #
使用多少自定义即可
vm.nr_hugepages_mempolicy = 0
vm.hugepages_treat_as_movable = 0
vm.nr_overcommit_hugepages = 0

我们可以手动定义将其当做共享空间来挂载,直接挂载到某个目录,而后创建文件快速删除很有用,有时候我们写脚本的时候可能会生成很多临时文件,如果我们将临时文件都放在这样的内存中,效果会更好

所以这时我们可以定义几个透明大页,将这些透明大页定义成共享内存空间并挂载

hugetable page主要是提高TLB性能,这样页表项就会变小,所以能提高TLB的性能

配置hugetable page

x86info �Ca | grep 'Data TLB'

dmesg

cat /proc/meminfo

更改大页

vim /etc/sysctl.conf

将值自定义更改:

vm.nr_hugepages = n

#hugepages = n

挂载

mkdir /hugepages

mount �Ct hugetlbfs none hugepages

通过挂砸可以将其当做内存磁盘来使用了,当然平时的时候不需要自己指定,如果不是自己想写脚本并创建临时文件的话是不需要挂载它的,只要启动透明大页,而后在mysql服务器上将服务器变量当做定义使用透明大页,它会自动使用

所以tlbfs只有在必要的时候,或想自己手动指定在某个位置使用内存磁盘的时候才有必要去定义的

定义透明大页的个数:

[root@node3 ~]# cd /proc/sys/vm/
[root@node3 vm]# cat nr_hugepages

0

将其值改为理想的数值即可,或者在grub中为内核启动的时候定义内核参数

 

观察内存的使用情况

比如观察内存有多少被交换出去或有多少被交换进来,page页面有多少被分配出去或有多少写入到磁盘中等

涉及命令:

vmstat -n 1 2

sar -r  1 2

1表示采样时间间隔

2表示采样时间次数

 

使用vmstat -n观察内存活动信息

 [root@node3 ~]#vmstat -n 1 2

procs -----------memory---------- ---swap-- -----io------system-- -----cpu-----

 r  b  swpd   free   buff cache   si   so   bi    bo   in  cs us sy id wa st

 0  0     0 1216352  10392 225308    0   0     0     1   3    5  0  0100  0 0 

 0  0     0 1216344  10392 225264    0   0     0     0 170  308  0  0100  0 0 

 

参数解释:

swap : 虚拟内存的使用情况,当然我们这里没用

    si: 从磁盘中读进来的swap数据量

    so: 写到swap中的数据量

 

free:空闲内存量

    buffer:用于buffer空间
    cache:如上

 

另外还有两个没有显示需要使用-a参数查看

inact: 非活动内存 意为已有一段时间没有被程序所使用了

但是inact非活动该内存有两类:

  ・干净页:  指的是没有被修改的,可以将其回收,直接清理即可

  ・脏页  :  指的是必须将其同步到磁盘上才可以回收资源

active :活动内存 意为正在被程序所使用的

 

如果我们发现大量的si so 意味着交换内存以及被使用了,而且有大量的换进换出,意味着物理内存不够用,那么提高性能的方法无非就是加大物理内存;

但是需要注意的是当观测一个值的时候,有可能会有一些比较独特的情况,比如CPU使用率100%并不意味着CPU慢,因为CPU可能花费很长时间去等待IO完成,也就是说去进行swap in/out  所以很多时候看上去CPU利用率高,但是最后发现是I/O的问题,完全是有可能的

如果出现这种I/O,由于是swap产生的io,意味着内存不够用,所以要做综合评判

 

使用sar -r 进行观测

[root@node3 ~]# sar -r 1

Linux 2.6.32-431.20.3.el6.x86_64 (node3.test.com) 09/14/2014    _x86_64_(4 CPU)

 

04:06:29 PM kbmemfreekbmemused  %memused kbbuffers  kbcached  kbcommit  %commit

04:06:30 PM   1216344   705768     36.72     10408   225348   1091764     27.16

04:06:31 PM  1216336    705776     36.72    10408    225348   1091764    27.16

04:06:32 PM  1216336    705776     36.72    10408    225348   1091764    27.16

04:06:33 PM  1216336    705776     36.72    10408    225348   1091764    27.16

04:06:34 PM  1216336    705776     36.72    10408    225348   1091764    27.16

04:06:35 PM  1216336    705776     36.72    10408    225348   1091764    27.16

04:06:36 PM  1216336    705776     36.72    10408    225348   1091764    27.16

需要关注前四个参数的值的变化

参数解释:

kbmemfree:  以kb为单位显示内存的空闲空间

kbmemused: 以kb为单位显示内裤空间的使用

memused :  内存使用百分比

kbbuffers:  略 

kbcached : 略

kbcommit  :内存的提交

需要关注的是前四个值,如果数据量变化非常频繁的话,则表明内存被频繁的使用/释放;

如果释放回收的比例过高,而free空间过小 use的空间过大,而且变化过于频繁的时候,那么很可能是内存活动剧烈导致的,有可能是像varnish之类的服务由于频繁的内存释放回收等实现缓存对象创建和清除的活动带来的,只要对比没有到100% 就可以任由他去 ,但是注意实时监控

 

使用sar -R 观测内存其活动速率 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

[root@node3 ~]# sar -R 1

Linux 2.6.32-431.20.3.el6.x86_64 (node3.test.com) 09/14/2014    _x86_64_(4 CPU)

 

04:08:42 PM   frmpg/s   bufpg/s  campg/s

04:08:43 PM   -33.00      0.00      0.00

04:08:44 PM     0.00      0.00      0.00

04:08:45 PM     0.00      0.00      0.00

04:08:46 PM     0.00      0.00      0.00

frmpg/s : 每秒释放了多少个内存页,如果我们想要知道多大内存需要将这个数值乘以4

bufpg/s : 每秒被用于哪来实现buffer的页面个数

campg/s : 如上,每秒被用于哪来实现cache的页面个数

bufpg+campg-frmpg = 真正释放的个数

如果一直是负值,那么内存空间肯定是一直有限的,总有一定时间总会被耗尽,所以一直为负值就意味着可能会内存泄露了

这个观测值还可以长时间评判出内存是否有泄露情况发生,释放和分配的值大致可以相同

 

使用sar -W查看交换内存使用情况

[root@node3 ~]# sar -W
Linux 2.6.32-431.20.3.el6.x86_64 (node3.test.com)     09/13/2014      _x86_64_     (4 CPU)

12:00:01 AM  pswpin/s pswpout/s
12:10:01 AM      0.00     0.00
12:20:01 AM      0.00     0.00
12:30:01 AM      0.00     0.00

由于没跑任何服务所以这里为0,如果有频繁的pswpin 和pswpout 就意味着我们的物理内存太小了

交换内存用了没有关系,但是变化量很小但是使用空间很大也没有问题

如果变化值很高,通常会有问题需要我们关注了

 

使用sar -B查看I/O使用情况

[root@node3 ~]# sar -B

Linux 2.6.32-431.20.3.el6.x86_64 (node3.test.com) 09/14/2014    _x86_64_(4 CPU)

 

12:00:01 AM pgpgin/s pgpgout/s   fault/s  majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s   %vmeff

12:10:01 AM     0.00      1.45     11.83     0.00      4.00      0.00     0.00      0.00      0.00

12:20:01 AM     0.00      0.82    147.74     0.00    176.60      0.00     0.00      0.00      0.00

12:30:01 AM     0.00      2.18      4.40     0.00      1.66      0.00     0.00      0.00      0.00

12:40:01 AM     0.00      1.30      3.31     0.00      1.53      0.00     0.00      0.00      0.00

12:50:01 AM     0.00      0.77    146.06     0.00    174.63      0.00     0.00      0.00     0.00

01:00:01 AM     0.01      2.14      5.73     0.00      1.80      0.00     0.00      0.00      0.00

pgpgin :   每秒页面载入个数

pgpgout:   页面写出个数,以页为单位直接与内核内存交互的,而内核内存最终是与I/O交互

#一通不同到磁盘中通常都是脏页,需要pgpgin一般需要用到buffer/cache

fault  :   每秒出现的异常个数

majflt :   大异常的个数

 

#以下参数不需要被关心

pgfree :每秒钟有多少个页被放到空闲列表中去,说明被回收回来的页面个数

pgscank:每秒被kswap所扫描的页面个数

pgscand:直接被内核扫描的页面个数

 

以上是跟真正I/O相关的参数(跟硬盘交互的时候数据载入内核内存并载入到进程内存中,或从脏页中写入到磁盘中的数据

 

题外:使用dstat观察内存状况

dstat是非常好用的工具,能客观明了的显示出内存当前使用情况,个人比较喜欢用,这里略过

[root@node3 ~]# dstat -g -m -s

---paging-- ------memory-usage----- ----swap---

  in   out | used buff  cach  free| used free

   0     0 | 496M 10.4M  220M 1151M|  0  2048M

   0     0 | 496M 10.4M  220M 1151M|  0  2048M

   0     0 | 496M 10.4M  220M 1151M|  0  2048M

   0     0 | 496M 10.4M  220M 1151M|  0  2048M

   0     0 | 496M 10.4M  220M 1151M|  0  2048M

 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

调整内核参数

・容量调节

比如我们内存空间一共只有1G的容量,而是否能让内存使用大于1G,大于物理内存则意味着要使用交换内存进行存储数据,也就意味着只要允许过量那就必然会使用交换内存

如果确确实实不能加物理内存不得不使用交换内存的时候,尤其是在批量处理的环境上,比如hadoop,其不提供实时处理的,所以批量提交处理作业,和提交作业的输出中间可能有一段时间间隔,这种情况下是允许可以过量使用内存的

涉及参数文件:

/proc/sys/vm/overcommit_memory

/proc/sys/vm/overcommit_ratio

/proc/sys/vm/max_map_count

  本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

・overcommit_memory

[root@node3 ~]# cat /proc/sys/vm/overcommit_memory

0

相关参数:

0 :默认设置,是否允许过量,由内核决定是否可以过量而且允许过量多少

1 :允许使用交换内存,但是不明确使用大小,有可能会导致崩溃的

2 :允许使用交换内存,但是过量多少是需要手动定义的

   本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

如果设定为2,那么可用总的内存大小是:所有的交换内存空间 + 物理内存空间的一部分

使用多少物理内存是由overcommit_ratio进行定义的内存比例,用这个比例乘以物理内存的大小再加上交换内存的大小就是所有可用的内存空间

 

・overcommit_ratio

    假如这个ratio 为0.5的话,swap为4G 那么最大可用内存空间为6G

    如果overcommit_ratio的值为0的话,那就意味着所有可用大小是交换内存的全部+物理内存x0% 最终还是4G  本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

 

很显然,如果交换内存是4G 物理内存也是4G 又通过这种方式定义最多只能使用4G,那就意味着交换内存可能会用到 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

如果将swapiness的参数设置为0,那么意味着尽量不使用交换内存,而我们这里又明确说明内存总共可用空间只有4G,因为我们设置overcommit_ratio为0 而overcommit_memory的值为2,那毫无疑问肯定总共大小为4G,那就意味着我们交换内存可能会派不上用场,这就起到类似禁用交换内存的效果

 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻! 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

有些场景下,如果我们期望尽可能不使用交换内存可用使用这种方式

swapiness = 0

overcommit_memory = 2

overcommit_ratio = 0

这是一个非常常见的内存内核优化机制

 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

 

进程间通信内存性能调节 

涉及参数配置文件路径:/proc/sys/kernel/

・msgmax

    进程间通信如果基于消息间通信的话有可能一个进程与N个进程交互

    如果各worker发现其处理速度很快的话,而master处理速度很慢,那同样的速率下一个进程只能处理有限的几个,那么则有很多会处于等待状态(将其放在队列中)

    所以其参数的意思为:以字节为单位,用来定义单个消息大小的,默认值为65536

・msgmnb

  以字节为单位,指定消息队列的大小,单个消息上限

・msgmni

  是否允许多少队列个数

 

假如一个队列为10k,那我们有10个队列,10个队列加一起则为100k也就是说一共允许使用多少个消息队列,而每个队列有多大,而每个队列中的消息有多大,都是通过以上三个参数进行定义的

如果某个进程通信量的确很大,而且单个消息量也大,那我们可以将单个队列长度进行调整,将单个消息的上限调整;如果消息量也很大,则可以增加队列数

前提是进程间通信是根据消息通信的,如果不是则进入第二种方法:

  本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

 

以共享内存作为通信方式

涉及参数配置文件路径:/proc/sys/kernel/

・shmmni

   可用于共享内存的最大内存大小,指的是片段,因为共享内存不一定是连续的,所以指的是用于共享内存的内存段的个数,默认值为4096

   有些服务,比如oracle,oracle内部有许多子进程这些进程各自负责不同的任务,而彼此之间通信都是基于共享内存所实现的,所以通常需要调整其值

・shmmax

    可允许最大共享内存片段(单个内存片段大小上限),64位系统默认值为68719476736,在红帽6.x 64位系统则不用调整了

・shmall

    单次在系统中可以使用的共享内存量,某一次申请共享内存,最多可申请多少个

    比如:一个片最大10k,一共4096片,我们规定一次只能使用20k,那么意味着我们最多可以使用2片;那么如果我们定义单片最大上限为20k,那么意味着一次只能申请一片。

     在红帽6.4,如果内存够多通常是不用调整的

・threads-max   本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

   最大线程,规定内核使用的最大线程数

  threads-max最小为20 

计算最大值:

  max_threads = mempages / (8 * /THREAD_SIZE / PAGE_SIZE )

  如果多个进程大小值通常很难平均的时候,这个值可能会用的到

 

与容量相关的文件系统可调整参数 

主要关心的参数:

・file-max 

设置最大的文件描述符

echo '*    -      nofile     65535 ' >>/etc/security/limits.conf

#nofile 表示所能打开的最大的文件数

 

・min_free_kbytes

最小空闲的内存空间,我们的物理空间不能全部分配出去,必须要预留一部分供内核所使用、分配,设置这个数值务必要小心,因为过高或过低都有风险的,多数情况下如果不清楚可以不调

 

・dirty_ratio

当物理内存中脏页比例超出一定比值的时候一定会使用pdflush定期刷写到硬盘上去,但是如果变化量非常快,如果不到一秒钟就会有很多,那么用定时刷写则效率会比较低

通常将脏页刷写到硬盘通常有两个策略

    ・按照时间,固定周期 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

    ・按照刷写的内容,达到一定比例,到达一定比值的时候

时间间隔越小就意味着刷鞋频率越高,频率越高就意味着数据在内存中可能丢失的越小,但是IO活动量就越大,所以很多时候取得一个理想值是很关键的

 

比如:如果有时候3秒钟的数据丢失,就意味着数据量可以在内存中存储3秒以上,意味着3秒刷写一次,那么IO量会降低,IO是性能的瓶颈所在

dirty_ratio默认值为20,当脏页比例所占据的总内存空间所达到了总内存空间的百分之二十之后则自动刷写到硬盘中

如果认为这个值比较低,可以将其调高,可以降低刷写次数,提高性能表现,但是可能会丢失数据,具体调整多少值需要自己去衡量

在对于数据要求非常高的场景中,比如数据库,这个值不可以调高;但是对于varnish这种内存缓存服务器来讲,缓存的数据丢失也没有关系,这样的话可以调高,但是缓存是不能够写数据的,或者说在内存中存储缓存是不可能刷写的硬盘上去的,但是有的时候需要的,比如用磁盘进行缓存数据,这时候可以极大的调整此值;

 

・dirty_background_ratio

与上面不同,此值定义全局百分比 本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

 

dirty_background_ratio和dirty_ratio的区别:

dirty_ratio是由当某个进程自己所使用的内存数据的脏页将达到总体内存的百分比,于是进程自动向内核申请激活pdflush 由pdflush将进程的脏页同步至磁盘(与单进程相关)

dirty_background_ratio: 如果某个进程使用比例都是5% 但是所有进程所占的比例加一起都有可能超过某一数值,所以所有数值加一起达到这个比例的时候则由内核启动pdflush,当某个进程自己的比例达到dirty_ratio的比例的时候,进程将自己向内核申请执行pdflush

以上是常调的两个参数

那么启动多少个pdflush线程比较合适:

一般默认而言,一个硬盘一个pfflush即可,多了反而会起到反作用

 

总结:对我们而言最常要调的有三组

1.swapinice overcommit

2.msgmax msgmin mnb

3.pdflush

而在有些特殊场景下,比如database 单进程大量使用的场景下,需要自己手动定义大页的,这样能够显著降低数据库的页表条目,以及提高tlb命中率的

 

以上,为linux内存调优的学习笔记,感谢各位

 

  本文来自 http://yijiu.blog.51cto.com/ 转载请与博主联系,翻版可耻!

 

本文出自 “心情依旧” 博客,转载请与作者联系!