当Transparent hugepage 遇到fork

        线上计数系统遇到一个奇怪的问题,进程在做备份时,系统内存迅速变小,25G内存被吃掉,最后进程大量占用swap,导致服务响应缓慢,SLA下降严重。

        最后发现跟Transparent hugepage相关,具体记录如下。

 

1 计数系统备份说明

        cache系统占用内存在10-100G级别,备份是在每日凌晨低峰时间进行,备份逻辑:主进程 fork,然后子进程执行落地任务,父进程继续响应请求,备份期间,系统变更量很少,单个kv的byte在64btes以内,变更的tps在100以下。

 

2 os版本与thp

        线上Linux内核2.6.38 ——2.7,而 Linux 内核在2.6.38之后,默认开启Transparent hugepage,之前那些没法从复杂的hugepage中获得好处的应用,现在不需要做任何修改也可以得到性能改善,预计性能提升在10%左右。

 

3 内存去向分析

        日志分析发现,整个备份过程持续10分钟,整个过程的修改kv的个数为 100*60*10=60000,有效内存变更 60000*64=约4M;

        fork过程中,父进程变更是一个cow的过程,可以先算最极端情况:即每次变更的kv分散在一个page中,来进行计算最大值;

        对于普通的page,应该占用的内存:4M * 4K=16G;所以这个过程最多占用16G;

        系统默认开启了THP,每个page变成了2M,所以这个过程的最大占用内存 4M*2M=8192G;

        由于kv的size很小,很多kv是在相同的page,所以实际占用内存在25G mem & 20G+ swap;

 

 

4 关闭THP

        关闭THP,重启计数服务,百G数据的备份过程,更新毫无压力。

        小结一下,fork 备份,主进程变更流程变为cow,而Linux默认启用THP,于是出现写放大(即便你更新1 byte,实际内存也可能需要新占用2M bytes),于是内存就成为了瓶颈,swap、响应慢,极端情况下被os干掉而crash 等都会出现。

 

5 如何关闭THP

1)boot时生效 修改grub.cfg

 

transparent_hugepage=never

2) runtime 是修改

 

# echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
# echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag

 

6 More about THP

        Transparent hugepage是一个hugepage管理的简化版,在Linux 2.6.38之后自动生效,只对anonymous mem生效,可以通过  grep -i AnonHugePages /proc/meminfo 查看实际使用情况。

        对于普通的cache应用,默认的THP有性能提升,但如果有fork 且 fork的时间较长,需要观测资源占用情况,必要时关闭THP。

        runtime 期间 关闭THP,之前已经分配的hugepage继续生效,只对新分配的page不再采用hugepage,os也不再scan & merge pages。

        进程可以通过madvise 进行设置是否启用THP:

#include <sys/mman.h>

int madvise(void *addr, size_t length, int advice);

 

 参考:

https://access.redhat.com/solutions/46111

http://lwn.net/Articles/423584/

http://lwn.net/Articles/423592/

 

        

猜你喜欢

转载自fishermen.iteye.com/blog/2288940
今日推荐