Linux主机内存评估手册-从零到无
--时间:2020年10月22日
--作者:飞翔的小胖猪
文档基于Centos Linux操作系统作为生产服务器运行环境。实时的查看分析当前系统内存的使用情况是否存在内存瓶颈,结合应用及现行业务需求分析判断主机系统是否满足进行内存升级扩容的条件。由于每个人对内存的使用及运行机制理解都不太一致,如出现偏差可按照自己的方法评估,文章只是提供一种方法,无法保证百分百准确性,一切以实际环境为导向。
一、说明
1.1 数据来源
内存分析数据主要通过free、vmstat、dstat等命令和/proc/下文件系统结合自己编写的脚本获取。
命令或文件名 |
作用 |
所属软件包 |
vmstat |
获取当前系统cpu、内存、io、swap、中断等信息。 |
procps-ng |
free |
获取当前系统内存使用率情况。 |
procps-ng |
/proc/zoninfo |
查看numca架构下每路CPU的内存及使用大小。 |
|
/proc/meminfo |
系统内存实时基础数据。 |
|
/proc/进程号/smaps |
指定进程使用内存情况。 |
|
numactl |
查看cpu及所属内存容量 |
|
1.2 关注点
固定配置:
内存配额值
是否使用swap
交换内存换入换出设置
CPU物理颗数(物理还是虚拟机)
实时信息:
大致的内存使用率。
实际内存使用率。
不活动buffer/cache内存值。
内存是否溢出。
numa架构每一路CPU使用及剩余内存值
业务方信息:
应用是否有内存大小监测功能,如果有最小值是多少。
是否强制要求剩余资源数值或百分比。
1.3 评估思路
①查看系统中当前内存大致使用情况。
②结合/proc/meminfo内存核实使用情况是否真实
(对于6及以下的版本free命令只会显示剩余内存,不会显示可用内存列,此时需要我们手动计算一下)
③查看当前系统所有进程线程实时占用内存情况包括共享内存。
④查看追踪应用是否存在内存溢出,如存在内存溢出需要业务调整相关函数释放申请内存。
⑤swap设置是否合理,有没有必要去除swap值。
⑥对比配额内存与实际使用内存值计算出百分比,结合业务特性同时咨询业务人员判断该主机内存是否满足现行业务需求。
二、操作方法
2.1 步骤
步骤和评估思路顺序一致。了解现行服务器主机的运行基础环境,通过命令查看服务器内存使用情况,结合业务实际情况分析内存是否满足业务需求。
1.确认主机环境如内存配置,cpu配置,主机类型,swap使用及亲和性。
2.使用free命令查看内存使用情况
3.查看/proc/meminfo文件了解cache/buffer及活动/非活动内存值。
4.使用脚本统计一下所有进程线程的真实使用内存值。
5.判断是否存在内存溢出。
6.根据收集到的数据列出表格分析实际业务占用内存值。
7.结合业务反馈信息判断当前分配内存是否满足业务需求。
2.2 确认主机配置
首先确认需要查看的主机的基础信息,以下提供了一个基础配置清单。
检测项目 |
情况说明 |
命令 |
主机类型 |
待测主机是物理服务器还是虚拟机机。 |
dmidecode -t 1 |
CPU颗数和核心数 |
服务器一共有多少颗CPU,每颗CPU有多少核。虚拟机除了直通模式外可以忽略掉该项。 |
lscpu | grep 'NUMA node(s):' |
内存配置 |
一共为服务器主机分配了多少内存值。 |
free -m |
swap设置 |
操作系统是否使用swap,如使用了swap那么换入换出亲和性为多少。如果使用free命令在swap行输出内容都为0表示没有设置swap。 |
free -m cat /proc/sys/vm/swappiness |
2.3 内存使用率
2.3.1 free命令查看
使用free命令查看内存,了解大致的内存使用情况,通过free命令可以查看到内存及swap分配及使用情况。对于一般的情况下使用free命令就行了。6的系统和7的系统在输出结果上存在一定的差异,Centos 8 请参考Centos 7。
Centos 6:
[root@oracle_pref ~]# free -m
结果说明:
Mem_total: 总的内存去除了锁定内存过后的一般会比分配内存少一点。
Mem_used:同等与已经mapping的内存,在内存映射表中已经绑定真实内存的地址的值。
Mem_free:完全没有mapping的。
Mem_shared:进程间共用的内存值。
Mem_buffers:基于磁盘的缓存。
Mem_cached:基于文件的缓存。
Swap_total:交换空间总容量大小。
Swap_used:交换空间已经使用的容量,内存换出到磁盘中的数量,一般是冷数据。
Swap_free:交换空间剩余容量。
Centos 7:
[root@oracle_pref ~]# free -m
结果说明:
Mem_total: 总的内存去除了锁定内存过后的一般会比分配内存少一点。
Mem_used:同等与已经mapping的内存,在内存映射表中已经绑定真实内存的地址的值。
Mem_free:完全没有mapping的。
Mem_shared:进程间共用的内存值。
Mem_buffers:基于磁盘的缓存。
Mem_cached:基于文件的缓存。
Swap_total:交换空间总容量大小。
Swap_used:交换空间已经使用的容量,内存换出到磁盘中的数量,一般是冷数据。
Swap_free:交换空间剩余容量。
关注点:
通过free命令我能够大体的了解到主机内存分配情况及粗略的内存使用情况,是否使用了swap等。如果没有使用swap同时free内存占total内存值的30%及以上则可以初步判断该机器内存配置充足。如果free内存值占total值20%及以下时我们需要进一步查看分析主机真实可回收利用内存,不能单凭free占比来判断主机内存使用情况。对于Centos 7.x系列及以上的操作可使用available列作为实际可用内存来看待。
对于free内存值还能多的情况下如果在大量的使用swap值同时已经使用的swap远远小于free值那么可以考虑关闭swap或向下调整swap使用积极度在/proc/sys/vm/swappiness中,默认该值为60。
2.3.2 /proc/meminfo文件查看
/proc 文件系统是一个虚拟文件系统,通过它可以使用一种新的方法在 Linux内核空间和用户间之间进行通信。在 /proc 文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段,但是与普通文件不同的是,这些虚拟文件的内容都是动态创建的。通过/proc/meminfo文件查看获取更详细得内存使用情况。free命令的数据来源于/proc/meminfo。
[root@oracle_pref ~]# cat /proc/meminfo
字段说明:
MemTotal:所有可用的内存大小,物理内存减去预留位和内核使用。系统从加电开始到引导完成,firmware/BIOS要预留一些内存,内核本身要占用一些内存,最后剩下可供内核支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的,重启会改变。 MemFree:表示系统尚未使用的内存。 MemAvailable:真正的系统可用内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存 Buffers:用来给块设备做缓存的内存,(文件系统的 metadata、pages) Cached:分配给文件缓冲区的内存,例如vi一个文件,就会将未保存的内容写到该缓冲区 SwapCached:被高速缓冲存储用的交换空间(硬盘的swap)的大小 active:经常使用的高速缓冲存储器页面文件大小 Inactive:不经常使用的高速缓冲存储器文件大小 Active(anon):活跃的匿名内存 Inactive(anon):不活跃的匿名内存 Active(file):活跃的文件使用内存 Inactive(file):不活跃的文件使用内存 Unevictable:不能被释放的内存页 Mlocked:系统调用 mlock 家族允许程序在物理内存上锁住它的部分或全部地址空间。这将阻止Linux 将这个内存页调度到交换空间(swap space),即使该程序已有一段时间没有访问这段空间 SwapTotal:交换空间总内存 SwapFree:交换空间空闲内存 Dirty:等待被写回到磁盘的 Writeback:正在被写回的 AnonPages:未映射页的内存/映射到用户空间的非文件页表大小 Mapped:映射文件内存 Shmem:已经被分配的共享内存 Slab:内核数据结构缓存 SReclaimable:可收回slab内存 SUnreclaim:不可收回slab内存 KernelStack:内核消耗的内存 PageTables:管理内存分页的索引表的大小 NFS_Unstable:不稳定页表的大小 Bounce:在低端内存中分配一个临时buffer作为跳转,把位于高端内存的缓存数据复制到此处消耗的内存 WritebackTmp:FUSE用于临时写回缓冲区的内存 CommitLimit:系统实际可分配内存 Committed_AS:系统当前已分配的内存 VmallocTotal:预留的虚拟内存总量 VmallocUsed:已经被使用的虚拟内存 VmallocChunk:可分配的最大的逻辑连续的虚拟内存 HardwareCorrupted:当系统检测到内存的硬件故障时删除掉的内存页的总量 AnonHugePages:匿名大页缓存 CmaTotal:连续可用内存总量 CmaFree:空闲连续可用内存 HugePages_Total:预留的大页内存总量 HugePages_Free:空闲的大页内存 HugePages_Rsvd:已经被应用程序分配但尚未使用的大页内存 HugePages_Surp:初始大页数与修改配置后大页数的差值 Hugepagesize:单个大页内存的大小 DirectMap4k:映射TLB为4kB的内存数量 DirectMap2M:映射TLB为2M的内存数量 DirectMap1G:映射TLB为1G的内存数量
关注点:
在/proc/meminfo文件中主要查看如下几行数据:MemTotal、MemFree、MemAvailable、Inactive、SReclaimable。其中MemAvailable行是主机实际可用内存值,包括free内存+可回收内存,Centos 6.x和Centos 7.x都有该值。如果这个值占比小于MemTotal的20%说明主机的内存使用率高于80%,可以考虑对内存进行扩容。在虚拟化平台可分配的内存紧张时也可以不对其进行扩容,但是需要一个周期性的数据作为支撑,比如一周或一个月为取值期间,内存使用占比都在80%左右最高峰值未超过90%,free内存值保持在10%及以上的水平。
通过查看MemFree 、Inactive、SReclaimable三行数据,然后把这三行数据相加可大致得出系统剩余可用内存。当然查看MemAvailable行数据比较直观方便。由于MemAvailable行包含可回收内存,内存在回收的时候同时也是需要的一点时间的,可能会对应性能存在一定的影响。一般情况定义可用的内存为MemAvailable的85%左右,如果该值小于MemFree则直接使用MemFree作为可用内存值。
2.3.3 进程使用内存查看
通过free命令和/proc/meminfo命令基本上已经知道了主机内存的一个使用情况,如空闲的内存值、实际可回收可用的内存值等信息。同时可以通过使用命令的方式收集现阶段系统中进程及线程使用的内存情况更进一步的了解系统内存具体情况。
[root@oracle_pref ~]# grep Pss /proc/[1-9]*/smaps | awk '{total+=$2}; END {printf "%d kB\n", total }'
关注点:
查询出来的数值时当前系统进程及线程实时的一个内存使用累加单位为KB包括共享内存值。该值不能完全的表示系统中所有内存用量,可以作为参考。
2.3.4 内存是否溢出
(可以忽略这一步,不管对任何指标做评估时很重要的一点就是利用本身存在的工具和已经具备的环境,切记不要在系统中安装或更新任何软件,除非你能够得到业务方首肯并且你能承受业务GG的压力)
内存溢出一般情况下是业务方开发人员逻辑设计错误导致申请内存而没有对内存进行释放导致内存溢出。低于4.1的内核可以跳过该步骤,因为检测需要使用到memleak 是 bcc 软件包中的一个工具。
使用top命令首先找到内存消耗大的进程记录其进程号。然后使用memleak -a -p 进程号 命令查看指定进程的内存分配与回收情况。
2.3.5 numa架构内存分布
NUMA 全称 Non-Uniform Memory Access为“非一致性内存访问”。这种构架下,不同的内存器件和CPU核心从属不同的 Node,每个 Node 都有自己的集成内存控制器,通俗来说就是每一颗物理CPU都有属于自己的物理内存,在使用时会优先使用属于自己的物理内存,如果属于自己的内存消耗完了就回去其他地方(其他CPU管辖的内存)索要资源。
CPU访问本地节点内存的速度时最快的,与其他CPU距离越远访问内存的速度就会越慢。所以在使用内存时应该优先使用属于CPU本地节点的内存,单个进程的内存需求不要超过单个物理CPU本地节点内存的最大值。
/proc/zoneinfo文件中jilu 了当前每一颗物理CPU存在的内存使用情况。
[root@oracle_pref ~]# numactl --hardware
[root@oracle_pref ~]# cat /proc/zoneinfo | grep -A50 Normal
关注点:
首先要注意numactl --hardware结果的size行和free行分别代表CPU本区域总内存和剩余内存。当前的CPU的内存内存具体使用率、内存回收情况。
/proc/zoneinfo文件中的处的 min、low、high,是内存三个阈值,而 free 是剩余内存页数,它跟后面的 nr_free_pages 相同。nr_zone_active_anon 和 nr_zone_inactive_anon,分别是活跃和非活跃的匿名页数。nr_zone_active_file 和 nr_zone_inactive_file,分别是活跃和非活跃的文件页数。
当某个 Node 内存不足时(通过min、low、high这三个值来判断)系统可以从其他 Node 寻找空闲内存,也可以从本地内存中回收内存。具体选哪种模式,你可以通过 /proc/sys/vm/zone_reclaim_mode 来调整。它支持以下几个选项:默认的 0 ,表示既可以从其他 Node 寻找空闲内存,也可以从本地回收内存。1、2、4 都表示只回收本地内存,2 表示可以回写脏数据回收内存,4 表示可以用 Swap 方式回收内存。
2.3.6 swap使用分析
Swap 把这些不常访问的内存先写到磁盘中,然后释放这些内存,给其他更需要的进程使用,swap作为操作的虚拟内存在一定程度上可保证业务正常运行,一般情况下不建议不使用swap内存。
[root@oracle_pref ~]# free -m [root@oracle_pref ~]# cat /proc/sys/vm/swappiness
关注点:
查看free输出结果在free空闲内存大于swap内存的时候可以不设置swap。free 命令结果中swap处于使用阶段那么还需观察一段时间判断其swap使用值情况,如果值远远小于free列值则可以调小echo n > /proc/sys/vm/swappiness使内存更倾向于文件页回收。
/proc/sys/vm/swappiness取值范围为0-100,值越大表示换出swap更积极,0也不代表不换出。echo n > /proc/sys/vm/swappiness命令为当前系统生效,重启后失效,需要永久设置在/etc/sysctl.conf添加vm.swappiness = 60行。
2.3.7 业务需求分析
整理以上几步收集的数据形成一个数据表,联系业务方说明主机内存使用具体情况程序是否存在逻辑错误等,结合业务实际需求判断是否需要扩容内存。最终形成一个简易的书面文件反馈业务方告知最终处理意见及方法。
三、总结
在实际的生产环境中大多情况下以上内容只能作为参考。对于内存的评估用得最多还是free命令,充其量再查看一下/proc/meminfo文件的内容。对于资源的评估不能仅靠实时数据,实时数据并不一定能全面的展现出主机的资源负载情况,还需要历史性能数据来配合分析评估,通过数据可以了解主机近段时间的负载情况及资源使用率趋势,才能准确的对系统做出分析评估。友情提示生产环境中一定要建立一套性能监控系统,不然很容易被吃麻麻鱼的。
PS:需要word文档的可以私聊我,如文中内容出现错误望指正,谢谢。