一个内存碎片化导致系统SYS CPU利用率过高问题分析

1、场景描述

生产机器pg_update升级进程完成后,调用postgres多进程进行SQL压测,发现性能大幅下降,SYS CPU占用很高

2、问题分析

     1)机器共2NODE节点,postgres基本都是跑在NODE1上,跑到后期,出现严重内存占用不均匀,NODE1上内存基本耗尽,NODE0还有不少内存。查看NUMA分配策略:

    一个内存碎片化导致系统SYS CPU利用率过高问题分析

    策略为默认策略,preferred node为当前节点(即本地节点),该策略下内存分配行为遵从:优先分配本地node内存,如果不足才会考虑分配另外节点,和此处NODE0还有大量内存不符。排除NUMA策略因素

   2sys 占用cpu过高

     perf热点分析:

    一个内存碎片化导致系统SYS CPU利用率过高问题分析

可以看出发生了大量的migrate_pages,函数调用关系:__alloc_pages_nodemask -> __alloc_pages_slowpath -> __alloc_pages_direct_compact -> try_to_compact_pages -> compact_zone_order -> compact_zone ->migrate_pages 页面迁移频繁会导致sysCPU占用率提高。页面迁移一个是由于内存确实不足,另外是由于内存碎片过多,满足不了连续大内存分配,本场景排除内存不足,所以初步判断是内存碎片过多。

3)查看budyinfoextfrag查看ZONE的碎片化程度

cat /proc/buddyinfo

Node 0, zone DMA32 225 240 368 422 251 97 26 11 7 4 105
Node 0, zone Normal 2721 3506 4141 2391 1467 761 286 64 10 0 0
Node 1, zone Normal 3369 7124 3901 2187 725 153 12 0 0 0 0

cat /sys/kernel/debug/extfrag/extfrag_index  extfrag_index越接近1,碎片率越高】

Node 0, zone DMA -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
Node 0, zone DMA32 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
Node 0, zone Normal -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.985 0.993
Node 1, zone Normal -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.970 0.985 0.993 0.997

可以看出,两个NODE节点连续大内存非常少,为了满足这种较大内存的分配,不得不频繁的在两个节点上做回收迁移操作。

4)调整watermark提前进行内存回收操作

由于本场景,NODE1内存即将耗尽时发生内存回收,会导致回收和分配不断的反复进行,震荡进行,表现为CPU突发性占用率变高,性能急剧下降。为了使回收变得更平缓,不那么急中进行,可调高watermark进行,

[[email protected] czh]# cat /proc/sys/vm/min_free_kbytes
90112

增加watermark

echo 2048000 > /proc/sys/vm/min_free_kbytes 

调整后再测试:

一个内存碎片化导致系统SYS CPU利用率过高问题分析

可以看出CPUsys利用率大幅下降。系统性能恢复正常。