[关闭]
@gy-ban 2016-11-27T09:30:21.000000Z 字数 4355 阅读 1183

linux内存使用之--slab

技术


背景

最近在查看zabbix监控的时候,发现一台服务器内存使用超过85%;而另外一个监控软件new relic则显示只使用了20%还不到。我只好登录到那台服务器进行查看:

  1. [bhuser@boohee-dragon ~]$ free -m
  2. total used free shared buffers cached
  3. Mem: 15950 15682 267 27 321 1625
  4. -/+ buffers/cache: 13735 2215
  5. Swap: 16383 44 16339

通过free查看确实使用了将近14G,然后我用top查看一下,到底是哪个进程吃了这么大内存:

  1. [bhuser@boohee-dragon ~]$ top
  2. top - 09:38:24 up 225 days, 18:14, 1 user, load average: 0.36, 0.34, 0.36
  3. Tasks: 288 total, 1 running, 287 sleeping, 0 stopped, 0 zombie
  4. Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
  5. Mem: 16333464k total, 16066764k used, 266700k free, 329620k buffers
  6. Swap: 16777212k total, 45060k used, 16732152k free, 1664812k cached
  7. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
  8. 3173 bhuser 20 0 8095m 1.4g 119m S 0.0 9.0 14198:25 java
  9. 23493 mysql 20 0 3582m 410m 5712 S 0.0 2.6 4286:26 mysqld
  10. 2364 rabbitmq 20 0 4206m 36m 1712 S 0.0 0.2 617:14.78 beam.smp
  11. 30104 zabbix 20 0 161m 29m 27m S 0.0 0.2 11:58.55 zabbix_server
  12. 30106 zabbix 20 0 161m 29m 27m S 0.0 0.2 12:01.10 zabbix_server
  13. 30102 zabbix 20 0 161m 29m 27m S 0.0 0.2 11:55.26 zabbix_server
  14. 30103 zabbix 20 0 161m 29m 27m S 0.0 0.2 11:59.26 zabbix_server
  15. 30087 zabbix 20 0 256m 28m 27m S 0.0 0.2 113:50.06 zabbix_server
  16. 30083 zabbix 20 0 256m 28m 27m S 0.0 0.2 113:48.63 zabbix_server
  17. 30084 zabbix 20 0 256m 28m 27m S 0.0 0.2 113:48.54 zabbix_server
  18. 30085 zabbix 20 0 256m 28m 26m S 0.0 0.2 113:42.51 zabbix_server
  19. 30086 zabbix 20 0 256m 28m 26m S 0.0 0.2 113:51.84 zabbix_server
  20. 24243 apache 20 0 408m 24m 4244 S 0.0 0.2 0:33.10 httpd
  21. 24105 apache 20 0 408m 24m 4220 S 0.0 0.2 0:37.66 httpd
  22. 31776 apache 20 0 407m 24m 4248 S 0.0 0.2 0:33.48 httpd
  23. 31771 apache 20 0 407m 24m 4248 S 0.0 0.2 0:38.53 httpd
  24. 31770 apache 20 0 407m 24m 4240 S 0.0 0.2 0:33.80 httpd

通过top查看,并没有发现大内存的进程存在;

然后使用ps统计了下所有进程占用的总内存:

  1. [bhuser@boohee-dragon ~]$ ps aux | awk '{mem += $6} END {print mem/1024/1024}'
  2. 2.17601

所有进程使用内存之和也就不过2G多,但系统为什么显示已经使用了14G,另外的12G内存到底被被谁占用了?还有就是new relic为什么监控的内存使用也只有2G,这难道还有什么隐情?

带着疑惑,我问了下google,许久之后才了解到,free没有专门统计另一项缓存: Slab

Slab

简介

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

查看slab缓存

  1. [bhuser@boohee-dragon ~]$ cat /proc/meminfo
  2. Slab: 11881152 kB
  3. SReclaimable: 11839140 kB
  4. SUnreclaim: 42012 kB

主要列出了与slab相关的信息,其它的都省略掉了;其中Slab:11881152kB表示slab使用的缓存;SReclaimable(Linux 2.6.19+):11839140kB都是clean的缓存,可回收的;SUnreclaim:42012kB
表示不可回收的。
那这将近12G的slab缓存到底用在哪里了,我们可以通过slabtop命令进行查看:

  1. Active / Total Objects (% used) : 58926402 / 59679718 (98.7%)
  2. Active / Total Slabs (% used) : 2968740 / 2968754 (100.0%)
  3. Active / Total Caches (% used) : 108 / 186 (58.1%)
  4. Active / Total Size (% used) : 11065539.12K / 11143861.49K (99.3%)
  5. Minimum / Average / Maximum Object : 0.02K / 0.19K / 4096.00K
  6. OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
  7. 58293780 58293780 26% 0.19K 2914689 20 11658756K dentry
  8. 1157656 417218 36% 0.10K 31288 37 125152K buffer_head
  9. 46688 46655 99% 0.98K 11672 4 46688K ext4_inode_cache
  10. 24409 23499 96% 0.05K 317 77 1268K anon_vma_chain
  11. 21868 19578 89% 0.55K 3124 7 12496K radix_tree_node
  12. 20272 20143 99% 0.03K 181 112 724K size-32
  13. 19399 19231 99% 0.20K 1021 19 4084K vm_area_struct
  14. 12862 11612 90% 0.06K 218 59 872K size-64
  15. 12312 12275 99% 0.14K 456 27 1824K sysfs_dir_cache
  16. 9581 8983 93% 0.05K 143 67 572K anon_vma
  17. 8480 8282 97% 0.07K 160 53 640K selinux_inode_security
  18. 8010 7210 90% 0.12K 267 30 1068K size-128
  19. 4800 4723 98% 0.19K 240 20 960K size-192
  20. 4668 4585 98% 0.58K 778 6 3112K inode_cache
  21. 4185 3534 84% 0.25K 279 15 1116K filp
  22. 3444 3017 87% 0.30K 287 12 1148K nf_conntrack_ffffffff81b280e0
  23. 2076 2028 97% 1.00K 519 4 2076K size-1024
  24. 1572 1559 99% 0.64K 262 6 1048K proc_inode_cache
  25. 1296 1275 98% 0.50K 162 8 648K size-512
  26. 1272 1161 91% 0.07K 24 53 96K Acpi-Operand

通过slabtop我们看到系统中有大量dentry(directory entry cache)占用内存,那个这个dentry是什么了?
dentry(directory entry cache)目录项高速缓存,是Linux为了提高目录项对象的处理效率而设计的;它记录了目录项到inode的映射关系。因此,当应用程序发起stat系统调用时,就会创建对应的dentry_cache项(更进一步,如果每次stat的文件都是不存在的文件,那么总是会有大量新的dentry_cache项被创建)。

回收slab缓存

通过/proc/sys/vm/drop_caches这个配置项,我们可以手动清除指定的可回收缓存(SReclaimable)

  1. echo 2 > /proc/sys/vm/drop_caches

需要注意的是,手动清除缓存可能会在一段时间内降低系统性能。原则上不推荐这么做,因为如果有需要,系统会自动释放出内存供其他程序使用。

另外,手动清除Slab缓存是一个治标不治本的办法。因为问题不在Slab,而在于我们那个会引起Slab缓存飙涨的进程(我这里应该是rsync)。实际操作的时候发现,清除缓存一段时间后,Slab缓存很快又会“反弹”回去。如果需要治本,要么搞定问题进程,要么修改系统配置。(目前这台服务器的问题进程还在分析当中。。。)

调整系统vm配置

通常不建议调整系统参数,这样风险比较大,除非你已经熟练的掌握。
/etc/sysctl.conf里有几个对内存管理影响比较大的配置

vm.vfs_cache_pressure
系统在进行内存回收时,会先回收page cache, inode cache, dentry cache和swap cache。vfs_cache_pressure越大,每次回收时,inode cache和dentry cache所占比例越大
vfs_cache_pressure默认是100,值越大inode cache和dentry cache的回收速度会越快,越小则回收越慢,为0的时候完全不回收

vm.min_free_kbytes
系统的"保留内存"的大小,"保留内存"用于低内存状态下的"atomic memory allocation requests"(eg. kmalloc + GFP_ATOMIC),该参数也被用于计算开始内存回收的阀值,默认在开机的时候根据当前的内存计算所得,越大则表示系统会越早开始内存回收。
min_free_kbytes过大可能会导致OOM,太小可能会导致系统出现死锁等问题

vm.swappiness
该配置用于控制系统将内存swap out到交换空间的积极性,取值范围是[0, 100]。swappiness越大,系统的交换积极性越高,默认是60,如果为0则不会进行交换。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注