记一次内存占用问题的调查

2018-12-07  本文已影响0人  鱼_cc1f

背景

随着我们中心服务部署的越来越多,一台B6服务器上面的Java应用也越来越多, 内存也所剩无几,但是物理内存还可以使用20个gb的时候 ,突然收到了内存报警邮件,也不得不让我们重视。

现象:

image.png

这时第一的反应就是有应用程序溢出了,但是使用ps命令相加后。发现各个应用的内存是出奇的稳定 。 查看内存的相关使用数据后,发现

$ cat /proc/meminfo
Slab:             21286092 kB
SReclaimable:      87980 kB
SUnreclaim:        66232 kB

这个时候发现 ,slab的内存已经将近使用掉了20个gb的内存了,这是啥概念,基本可以顶一个头像服务了(头像服务也需要16gb的内存),在这种使用率的情况下,具体再看了一下redhat对这一块内存使用的简介:

Slab Allocation是Linux 2.2之后引入的一个内存管理机制,专门用于缓存内核的数据对象,可以理解为一个内核专用的对象池,可以提高系统性能并减少内存碎片。(Linux 2.6.23之后,SLUB成为了默认的allocator。)

其实发现 ,这一块内存是用于非常 小的一些文件做缓存使用的, 查看当前的服务器的slab的使用情况下来看是:


image.png

发现有可能是打开的文件太多, 在三点的时候 ,反而是我们业务的低峰,到底是啥东西占着呢?
继续看监控会发现 ,其实三点的时候 。 会有不少的请求打过来,会重新连接ssl, 这个时候 发现 ,可能是ssl连接的时候 ,使用了这么多内存?
带着比较疑惑的感情,在redhat的bug上面找了一下,好像aliyun和huawei的工程师也都发现了这个毛病,具体的bug如下:

https://bugzilla.redhat.com/show_bug.cgi?spm=a2c4e.11153940.blogcont131870.18.3fa96a80O3Tgco&id=1044666

是由于nss 组件 ,在centos 6的这个版本下,会有问题,具体的代码如下:


     env = PR_GetEnv("NSS_SDB_USE_CACHE");

     if (env && PORT_Strcasecmp(env,"no") == 0) {
    enableCache = PR_FALSE;
     } else if (env && PORT_Strcasecmp(env,"yes") == 0) {
    enableCache = PR_TRUE;
     } else {
    char *tempDir = NULL;
    PRUint32 tempOps = 0;
    /*
     *  Use PR_Access to determine how expensive it
     * is to check for the existance of a local file compared to the same
     * check in the temp directory. If the temp directory is faster, cache
     * the database there. */
    tempDir = sdb_getTempDir(sqlDB);
    if (tempDir) {
        tempOps = sdb_measureAccess(tempDir);
        PORT_Free(tempDir);

        /* There is a cost to continually copying the database. 
         * Account for that cost  with the arbitrary factor of 10 */
        enableCache = (PRBool)(tempOps > accessOps * 10);
    }
    }


主要的情况还是这个地方 ,在证书sll验证的时候 ,若是证书链的话。会为每一个session会话存储一个cache的,这里若是没有配置环境变量的话。就会走到这里( 老的版本,新的版本增加了下层的校验,不作path空校验), 证书链上面的每一个key都会缓存

tempOps = sdb_measureAccess(tempDir);

所以上图中有那么多entry 就是由于 这里导致的

解决办法 :
1、在cenots 6的版本中升级nss *的所有的组件,需要在环境变量中,增加NSS_SDB_USE_CACHE =yes( 强制清除slab风险很高,请不要操作,容易炸 ,请不要操作)
2、 升级centos 7
最终的内存线图(右边的上升是正常的上升,服务发布了)


image.png
上一篇 下一篇

猜你喜欢

热点阅读