优化系统缓存
缓存命中率
命中率越高,表示使用缓存带来的收益越高,应用程序的性能也就越好。
cachestat 和 cachetop工具
- 安装工具:
yum install -y bcc-tools
export PATH=$PATH:/usr/share/bcc/tools
- 使用说明:
cachestat 使用示例:
cachestat 1 5
HITS MISSES DIRTIES HITRATIO BUFFERS_MB CACHED_MB
19220 0 80 100.00% 424 9536
677 0 78 100.00% 424 9536
52014 0 64 100.00% 424 9536
5213 0 52 100.00% 424 9536
44819 0 42 100.00% 424 9536
- MISSES ,表示缓存未命中的次数;
- HITRATIO ,表示缓存命中率;
- DIRTIES, 表示新增到缓存中的脏页数;
- BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;
- CACHED_MB 表示 Cache 的大小,以 MB 为单位。
cachetop 输出示例
08:03:16 Buffers MB: 424 / Cached MB: 9538 / Sort: HITS / Order: descending
PID UID CMD HITS MISSES DIRTIES READ_HIT% WRITE_HIT%
3965464 UNKNOWN( mysqlchecker 4631 0 0 100.0% 0.0%
3965540 root curl 2318 0 0 100.0% 0.0%
3965517 root runc 2127 0 0 100.0% 0.0%
3965427 root ps 1704 0 0 100.0% 0.0%
指定文件的缓存情况
pcstat工具
- 安装工具
go install github.com/tobert/pcstat@latest
参考:pcstat
- 使用示例
pcstat /bin/ls
+---------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|---------+----------------+------------+-----------+---------|
| /bin/ls | 133792 | 33 | 0 | 000.000 |
+---------+----------------+------------+-----------+---------+
内存泄露问题处理
- 使用
vmstat查看内存是否持续增长
# 每隔3秒输出一组数据
$ vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 6601824 97620 1098784 0 0 0 0 62 322 0 0 100 0 0
0 0 0 6601700 97620 1098788 0 0 0 0 57 251 0 0 100 0 0
0 0 0 6601320 97620 1098788 0 0 0 3 52 306 0 0 100 0 0
0 0 0 6601452 97628 1098788 0 0 0 27 63 326 0 0 100 0 0
2 0 0 6601328 97628 1098788 0 0 0 44 52 299 0 0 100 0 0
0 0 0 6601080 97628 1098792 0 0 0 0 56 285 0 0 100 0 0
从上述输出可以看到,内存 free 列持续减少,说明系统内存持续增长。
- 指定进程内存泄漏分析工具
memleak
memleak是 bcc 软件包里面的工具,需要提前安装
memleak -p $(pidof app) -a
Attaching to pid 12512, Ctrl+C to quit.
[03:00:41] Top 10 stacks with outstanding allocations:
addr = 7f8f70863220 size = 8192
addr = 7f8f70861210 size = 8192
addr = 7f8f7085b1e0 size = 8192
addr = 7f8f7085f200 size = 8192
addr = 7f8f7085d1f0 size = 8192
40960 bytes in 5 allocations from stack
fibonacci+0x1f [app]
child+0x4f [app]
start_thread+0xdb [libpthread-2.27.so]
内存性能分析思路
- 先用 free 和 top,查看系统整体内存的使用情况。
- 再用 vmstat 和 pidstat,观察一段时间的变化趋势,从而判断出内存问题的类型。
-
最后进行详细分析,比如内存分配分析,缓存/缓冲区分析,具体的进程内存使用情况分析等。
image.png
根据这个图,举几个常用分析的例子:
- 当通过 free,发现大部分内存都被缓存占用后,可以使用 vmstat 或者 sar 观察一下缓存的变化趋势,确认缓存的使用是否还在继续增大。
如果继续增大,则说明导致缓存升高的进程还在运行,那你就能用缓存 / 缓冲区分析工具(比如 cachetop、slabtop 等),分析这些缓存到底被哪里占用。 - 当 free 一下,发现系统可用内存不足时,首先要确认内存是否被缓存 / 缓冲区占用。排除缓存 / 缓冲区后,你可以继续用 pidstat 或者 top,定位占用内存最多的进程。
找出进程后,再通过进程内存空间工具(比如 pmap),分析进程地址空间中内存的使用情况就可以了。 - 当通过 vmstat 或者 sar 发现内存在不断增长后,可以分析中是否存在内存泄漏的问题。
比如你可以使用内存分配分析工具 memleak ,检查是否存在内存泄漏。如果存在内存泄漏问题,memleak 会为你输出内存泄漏的进程以及调用堆栈。
常用工具查询列表:
image.png
常见的内存优化思路
- 最好禁止 Swap。如果必须开启 Swap,降低 swappiness 的值,减少内存回收时 Swap 的使用倾向。
- 减少内存的动态分配。比如,可以使用内存池、大页(HugePage)等。
- 尽量使用缓存和缓冲区来访问数据。比如,可以使用堆栈明确声明内存空间,来存储需要缓存的数据;或者用 Redis 这类的外部缓存组件,优化数据的访问。
- 使用 cgroups 等方式限制进程的内存使用情况。这样,可以确保系统内存不会被异常进程耗尽。
- 通过 /proc/pid/oom_adj ,调整核心应用的 oom_score。这样,可以保证即使内存紧张,核心应用也不会被 OOM 杀死。









网友评论