linux内存合并分区,Linux内存拾遗

管理内存是操作系统的核心职责之一。Linux系统把内存分页管理,每一页(page)的大小可以用命令getconf PAGESIZE查看,单位是字节(Byte),Linux默认的页大小为4KB。[root@localhost~]# getconf PAGESIZE

4096

内存的总体情况可以通过cat /proc/meminfo查看[root@localhost~]# cat/proc/meminfo

MemTotal:65751096kB

MemFree:64077144kB

MemAvailable:64061216kB

Buffers:2076kB

Cached:404000kB

SwapCached:0kB

Active:759688kB

Inactive:177952kB

Active(anon):532748kB

Inactive(anon):17212kB

Active(file):226940kB

Inactive(file):160740kB

Unevictable:0kB

Mlocked:0kB

SwapTotal:33554428kB

SwapFree:33554428kB

Dirty:8kB

Writeback:0kB

AnonPages:531796kB

Mapped:54212kB

Shmem:18396kB

Slab:194488kB

SReclaimable:72256kB

SUnreclaim:122232kB

KernelStack:13360kB

PageTables:12020kB

NFS_Unstable:0kB

Bounce:0kB

WritebackTmp:0kB

CommitLimit:66429976kB

Committed_AS:2371680kB

VmallocTotal:34359738367kB

VmallocUsed:415224kB

VmallocChunk:34308620284kB

HardwareCorrupted:0kB

AnonHugePages:290816kB

HugePages_Total:0

HugePages_Free:0

HugePages_Rsvd:0

HugePages_Surp:0

Hugepagesize:2048kB

DirectMap4k:217920kB

DirectMap2M:8124416kB

DirectMap1G:60817408kB

本文主要总结一下在运维实践中遇到的跟内存有关的问题或技巧。

buffer cache和swap

free是系统管理员查看服务器内存情况常用的命令,在CentOS7.4上输出内容如下:[root@localhost ~]# free

total        used        free      shared    buff/cache   available

Mem:         65751096     1079756    64070284         18396      601056    64054484

Swap:        33554428           0    33554428

从CentOS7系列版本开始,buffer和cache被合并为一列显示了,在之前的版本中是分开的。虽然被合并显示,但是它们保存的内容是不同的。

lBuffer——顾名思义是缓冲区的意思,由于内存访问速度远超硬盘等块设备,所以Linux系统把文件系统中访问过的元数据缓存在buffer中,以提高下次访问的速度。

lCache——cache是缓存区,在内存足够的情况下,Linux系统总是倾向于把打开过的程序、文件内容缓存在内存中,所以长时间运行的服务器cache都比较大,这么做是为了下次访问这些文件更快。当有程序申请内存且空闲内存不足时,系统会释放cache以腾出空间。

lSwap——在以前内存还是很金贵的资源时,为了“扩展”服务器有限的内存,Linux允许在块设备上划分出一块空间,将内存中不经常被访问的页置换到这里,腾出内存给处于活跃状态的进程,这个空间就是交换分区swap。由于硬盘比内存访问性能低,所以使用swap分区会降低性能。现在的服务器有一两百GB内存已经不稀奇了,似乎swap已经没有存在的意义了,其实不然,即使swap现在已经很少被用到了,我们在部署服务器时仍应该分配一个合理的空间给swap,有swap分区作为缓冲,可以避免系统因内存不足开始自动kill进程引起宕机,给运维人员处理内存饱和的问题争取时间,性能损失总比宕机要好。

实际情况中,有时会遇到有的服务器内存被cache占用完,系统开始把部分内存置换到swap中,导致性能急剧下降。这种情况下可以清理cache,释放出内存给进程用。清理cache的过程如下:[root@localhost~]# sync

[root@localhost~]# echo3 > /proc/sys/vm/drop_caches

为了安全,清理cache前要先执行sync,使内存中的dirty数据落盘。

drop_caches取值范围为1,2,3,

1表示清理页面缓存;

2表示清理页面缓存和目录缓存;

3表示清理页面缓存、目录缓存和inode缓存。

为了减小系统使用swap分区的倾向,还有个内核参数可以调整——swappiness。swappiness的取值范围是0到100,数值越大系统使用swap分区的倾向就越大,为0时表示完全不使用swap。鉴于上面介绍过swap分区存在的必要性,我们不应该把swappiness设置为0,而应该设置为1,让系统尽可能避免使用swap分区,同时并不完全放弃使用swap的可能。[root@localhost~]# echo"vm.swappiness = 1" >> /proc/sys/vm/swappiness

[root@localhost~]# sysctl -p

vm.swappiness= 1

KSM

KSM(Kernel SamePage Merging)是一种压缩内存的技术,顾名思义就是将内存中内容相同的页进行合并以节省内存空间,当有进程需要修改该内存页的内容时,再将其拷贝一份再修改,也就是“写时复制copy on write”。KSM最早是为了优化qemu-kvm宿主机内存使用而诞生的,当一台宿主机上运行多个相同操作系统的虚拟机时,有很多内存页内容相同可以合并。KSM在CentOS6和CentOS7上是默认打开的,有两个相关服务:

lksm

lKsmtuned

ksmtuned依赖ksm服务,它的主体/usr/sbin/ksmtuned是一个shell脚本,通过读取配置文件/etc/ksmtuned.conf中的参数,对ksm的行为进行控制。在ksmtuned的控制下,ksm并不是一直在工作,它只在参数限定的条件达到的情况下工作,ksm是否在工作可以通过cat /sys/kernel/mm/ksm/run命令查看,0表示ksm没有在工作,1表示ksm在工作。

通过分析/usr/sbin/ksmtuned,可以了解配置文件中几个主要参数的含义:

lKSM_MONITOR_INTERVAL=60 默认值为60,单位秒,表示每隔60秒,ksmtuned工作一次,扫描系统内存使用情况并据此调整ksm参数。数值越小ksmtuned工作频率越高,对cpu消耗越多;

lKSM_SLEEP_MSEC=10 默认值为10,最小值也为10,单位毫秒,ksm扫描内存页的间隔,数值越小ksm扫描内存页的频率越高,对cpu消耗越多。对应的内核参数是/sys/kernel/mm/ksm/sleep_millisecs;

lKSM_NPAGES_BOOST=300

KSM_NPAGES_DECAY=-50

KSM_NPAGES_MIN=64

KSM_NPAGES_MAX=1250

这一组参数用于设置ksm一次扫描多少内存页,对应内核参数/sys/kernel/mm/ksm/pages_to_scan。pages_to_scan的值在KSM_NPAGES_MIN和KSM_NPAGES_MAX之间波动,如果空闲内存大于临界值,需要降低ksm工作强度,则每次ksmtuned工作都会调低pages_to_scan 300(KSM_NPAGES_BOOST)页;反之,需要增强ksm工作强度,则每次ksmtuned工作会调高pages_to_scan 50(KSM_NPAGES_DECAY)页。

lKSM_THRES_COEF=20

KSM_THRES_CONST=2048

这两个参数用于设置一个内存临界值,总内存的20%(KSM_THRES_COEF)和2048MB(KSM_THRES_CONST)两者之间取大者。当“所有qemu进程的内存”和临界值之和小于“总内存”,并且空闲内存大于临界值时,ksm停止工作,/sys/kernel/mm/ksm/run被置0;其他情况下,ksm处于工作状态,/sys/kernel/mm/ksm/run被置1。如果想让ksm早点开始工作,可以调高临界值。

常见的ksmtuned.conf配置如下:# Configuration file for ksmtuned.

# How long ksmtuned should sleep between tuning   adjustments

KSM_MONITOR_INTERVAL=60

# Millisecond sleep between ksm scans for 16Gb server.

# Smaller servers sleep more, bigger sleep less.

KSM_SLEEP_MSEC=10

KSM_NPAGES_BOOST=300

KSM_NPAGES_DECAY=-50

KSM_NPAGES_MIN=64

KSM_NPAGES_MAX=1250

KSM_THRES_COEF=20

KSM_THRES_CONST=2048

# uncomment the following if you want ksmtuned debug   info

LOGFILE=/var/log/ksmtuned

DEBUG=1

日志/var/log/ksmtuned记录了ksmtuned每次执行的结果:[root@localhost ~]# tail -100f   /var/log/ksmtuned

Thu Jan 18 11:29:18 CST 2018: total   65751096

Thu Jan 18 11:29:18 CST 2018: sleep 10

Thu Jan 18 11:29:18 CST 2018: thres   13150219

Thu Jan 18 11:30:18 CST 2018: committed 0   free 64470428

Thu Jan 18 11:30:18 CST 2018: 13150219   < 65751096 and free > 13150219, stop ksm

我的测试机内存比较空闲,ksm一直处于stop状态,下面我把KSM_THRES_COEF调大到100然后systemctl restart ksmtuned,强行让ksm工作,然后看看效果:[root@localhost~]# cat/sys/kernel/mm/ksm/run

1

[root@localhost~]# tail-10f/var/log/ksmtuned

Thu Jan18 15:05:05CST2018:sleep10

Thu Jan18 15:05:05CST2018:thres65751096

Thu Jan18 15:06:05CST2018:committed0free64467712

Thu Jan18 15:06:05CST2018: 65751096 > 65751096,start ksm

Thu Jan18 15:06:05CST2018: 64467712 < 65751096,boost

Thu Jan18 15:06:05CST2018:KSMCTL start300 10

Thu Jan18 15:07:05CST2018:committed0free64468624

Thu Jan18 15:07:05CST2018: 65751096 > 65751096,start ksm

Thu Jan18 15:07:05CST2018: 64468624 < 65751096,boost

Thu   Jan18 15:07:05CST2018:KSMCTL start600 10

/sys/kernel/mm/ksm/pages_sharing记录了有多少内存页正在使用被合并的内存页,也就是实际节省的内存页数。页数乘以PAGESIZE就可以计算出实际节省的内存,命令如下:echo“$(($(cat   /sys/kernel/mm/ksm/pages_sharing)*$(getconf PAGESIZE)/1024/1024))MB”

NUMA

给有两路cpu的服务器插过内存的同学应该知道,每路cpu都有自己的内存条插槽。这是解决多cpu扩展问题的一种架构——NUMA,Non-Uniform Memory Access,非一致内存访问。为什么叫“非一致”呢?因为一个cpu访问自己的本地内存比访问别的cpu的内存速度要快,所以叫非一致。

numactl是一个管理numa的命令行工具,如果系统默认没有这个命令,可以通过yum install numactl安装。numactl –hardware可以查看cpu和内存的硬件情况,下面是一台4路服务器上执行命令的结果:[root@localhost~]# numactl--hardware

available: 4nodes(0-3)

node0cpus: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60

node0size: 16338MB

node0free: 15279MB

node1cpus: 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61

node1size: 16384MB

node1free: 15762MB

node2cpus: 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62

node2size: 16384MB

node2free: 15646MB

node3cpus: 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63

node3size: 16384MB

node3free: 15861MB

node distances:

node0123

0:10203020

1:20102030

2:30201020

3:20302010

4路cpu就是4个numa nodes,每个nodes有16G的本地内存,整个服务器总共有64G物理内存。

numastat -c 可以查看指定进程的内存使用情况:[root@localhost~]# numastat -c nginx

Per-node process memory usage(inMBs)

PID              Node0Node1Node2Node3Total

------------------- ------ ------ ------ -----

74675 (nginx)00101

74676 (nginx)00203

74677 (nginx)10103

74678 (nginx)11103

74679 (nginx)00203

74680 (nginx)10103

74681 (nginx)01103

74682 (nginx)00203

74683 (nginx)10103

74684 (nginx)00203

74685 (nginx)01103

74686 (nginx)10103

74687 (nginx)00203

74688 (nginx)00203

74689 (nginx)01103

74690 (nginx)10103

74691 (nginx)00203

74692 (nginx)00203

74693 (nginx)01103

74694 (nginx)20113

74695 (nginx)00203

74696 (nginx)00203

74697 (nginx)11103

74698 (nginx)10103

74699 (nginx)00203

------------------- ------ ------ ------ -----

Total18635565

上面的输出可以看出各个nginx进程的内存分散在了4个node上。

CentOS6和Centos7上都有一个叫numad的服务,这个服务负责在numa架构下调度各节点的内存分配,使内存分配具有cpu亲和性,例如一个线程运行在cpu0上,它申请的内存页将尽量从cpu0的本地内存中分配。这个服务默认没有开启,因为这种内存分配策略并不适合所有场景,当服务器上运行了很多应用程序或很多虚拟机时,numad具有cpu亲和性的内存分配方式可以提高性能,但是如果整个系统只运行一个高内存消耗的程序如数据库,numad反而会导致内存分配不均而降低性能,因此数据库服务器建议不要开启numad服务。

Linux系统中还有一个numa自动平衡策略,系统通过自动调配内存以求在各个numa nodes的内存使用率处于相对平衡的状态,这个策略可以通过修改内核参数/proc/sys/kernel/numa_balancing控制。关闭numa自动平衡策略:echo 0 > /proc/sys/kernel/numa_balancing;开启numa自动平衡策略:echo 1 > /proc/sys/kernel/numa_balancing。这个策略系统默认也没开启。

关于Linux内存的小技巧暂时只想到这么多,感谢阅读!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值