優(yōu)化系統(tǒng)緩存
緩存命中率
命中率越高,表示使用緩存帶來的收益越高,應(yīng)用程序的性能也就越好。
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 ,表示緩存未命中的次數(shù);
- HITRATIO ,表示緩存命中率;
- DIRTIES, 表示新增到緩存中的臟頁數(shù);
- 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 |
+---------+----------------+------------+-----------+---------+
內(nèi)存泄露問題處理
- 使用
vmstat查看內(nèi)存是否持續(xù)增長
# 每隔3秒輸出一組數(shù)據(jù)
$ 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
從上述輸出可以看到,內(nèi)存 free 列持續(xù)減少,說明系統(tǒng)內(nèi)存持續(xù)增長。
- 指定進程內(nèi)存泄漏分析工具
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]
內(nèi)存性能分析思路
- 先用 free 和 top,查看系統(tǒng)整體內(nèi)存的使用情況。
- 再用 vmstat 和 pidstat,觀察一段時間的變化趨勢,從而判斷出內(nèi)存問題的類型。
-
最后進行詳細分析,比如內(nèi)存分配分析,緩存/緩沖區(qū)分析,具體的進程內(nèi)存使用情況分析等。
image.png
根據(jù)這個圖,舉幾個常用分析的例子:
- 當通過 free,發(fā)現(xiàn)大部分內(nèi)存都被緩存占用后,可以使用 vmstat 或者 sar 觀察一下緩存的變化趨勢,確認緩存的使用是否還在繼續(xù)增大。
如果繼續(xù)增大,則說明導(dǎo)致緩存升高的進程還在運行,那你就能用緩存 / 緩沖區(qū)分析工具(比如 cachetop、slabtop 等),分析這些緩存到底被哪里占用。 - 當 free 一下,發(fā)現(xiàn)系統(tǒng)可用內(nèi)存不足時,首先要確認內(nèi)存是否被緩存 / 緩沖區(qū)占用。排除緩存 / 緩沖區(qū)后,你可以繼續(xù)用 pidstat 或者 top,定位占用內(nèi)存最多的進程。
找出進程后,再通過進程內(nèi)存空間工具(比如 pmap),分析進程地址空間中內(nèi)存的使用情況就可以了。 - 當通過 vmstat 或者 sar 發(fā)現(xiàn)內(nèi)存在不斷增長后,可以分析中是否存在內(nèi)存泄漏的問題。
比如你可以使用內(nèi)存分配分析工具 memleak ,檢查是否存在內(nèi)存泄漏。如果存在內(nèi)存泄漏問題,memleak 會為你輸出內(nèi)存泄漏的進程以及調(diào)用堆棧。
常用工具查詢列表:

image.png
常見的內(nèi)存優(yōu)化思路
- 最好禁止 Swap。如果必須開啟 Swap,降低 swappiness 的值,減少內(nèi)存回收時 Swap 的使用傾向。
- 減少內(nèi)存的動態(tài)分配。比如,可以使用內(nèi)存池、大頁(HugePage)等。
- 盡量使用緩存和緩沖區(qū)來訪問數(shù)據(jù)。比如,可以使用堆棧明確聲明內(nèi)存空間,來存儲需要緩存的數(shù)據(jù);或者用 Redis 這類的外部緩存組件,優(yōu)化數(shù)據(jù)的訪問。
- 使用 cgroups 等方式限制進程的內(nèi)存使用情況。這樣,可以確保系統(tǒng)內(nèi)存不會被異常進程耗盡。
- 通過 /proc/pid/oom_adj ,調(diào)整核心應(yīng)用的 oom_score。這樣,可以保證即使內(nèi)存緊張,核心應(yīng)用也不會被 OOM 殺死。
