查看Linux内存剩余 ,你真的理解buffer和cache吗

作为Linux系统使用者,平时最关心的事情之一就是监控服务器的内存可用大小了。内存作为不可压缩资源,一旦超出使用就会导致应用出现OOM( Out Of Memory),某些应用就会强行被系统干掉。虽然可以调整应用的优先级让系统优先考虑干掉别的应用,但是出现OOM本身就说明了资源的不充足。

所以监控内存,跟查看内存剩余大小是很基础的一环。

查看内存可用大小的指令有很多,比如:
free -m
或者

vmstat
或者

cat /proc/meminfo
都可以查看当前可用的内存大小

free -m

free命令由procps.*.rpm提供(在Redhat系列的OS上)。free命令的所有输出值都是从/proc/meminfo中读出

在centos6中显示

             total       used       free     shared    buffers     cached
Mem:         32109      31854        254          0        162      17294
-/+ buffers/cache:      14398      17710
Swap:        18431       1633      16798

在centos7中显示

              total        used        free      shared  buff/cache   available
Mem:           1839        1221          77           3         540         445
Swap:          4095           0        4095

我们可以看到两个系统版本的free -m 显示的内容是有差别的。

先解释一下各列的意思:

  • total: 就是系统总共的内存值

  • used: 系统已经使用的内存值

  • free:系统剩余未使用的内存

  • shared:系统用来共享的内存值

在centos6中,

(-/+ buffers/cache):

(-buffers/cache) used内存数:(指的第一部分Mem行中的used – buffers – cached)

(+buffers/cache) free内存数: (指的第一部分Mem行中的free + buffers + cached)

在centos7中,系统剩余可用内存就在Mem那行中available那列的值

vmstat

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
3  0      0  79456 124200 429484    0    0     1     6    0    0  1  0 99  0  0

在centos6跟centos7中显示都一样

这里我们只关注memory部分

cat /proc/meminfo

MemTotal:        1883724 kB
MemFree:           72280 kB
MemAvailable:     448864 kB
Buffers:          124232 kB
Cached:           364804 kB
.
.
.
Slab:              64856 kB

从上面的例子看,其它内存部分都比较清晰,我们这里就重点讨论Buffer跟Cache。

从字面上来说,Buffer 是缓冲区,而 Cache 是缓存,两个指标都是数据在内存中的临时存储。

为了进一步清楚Buffers 跟Cache的意思,我们可以man free一下,得到以下解释:

    cache  Memory used by the page cache and slabs (Cached and Slab in /proc/meminfo)
    buff/cache
           Sum of buffers and cache

Buffers 是内核缓冲区用到的内存,对应的是 /proc/meminfo 中的 Buffers 值。

Cache 是内核页缓存和 Slab 用到的内存,对应的是 /proc/meminfo 中的 Cached 与 Slab 之和。

这里告诉我们的是这些数据都是来自/proc/meminfo ,但是具体的含义并没有说清楚。

这个时候我们通常情况下都会去百度或者谷歌一下,虽然大多数情况都可以找到一个答案。但是,筛查结果且不说耗费精力,也可能因为你的内核版本,性能工具版本的不同而有差别。而且可能因为博客作者不严谨,也是遇到问题,然后网上一查,没有核查,然后自己随手做了笔记,然后Po到网上当记录了。

那还有没有更简单,更准确的方法来查buffer跟cache呢?

上面的vmstat 跟free 其实都是读取/pro/meminfo文件的信息,既然在/pro/meminfo 中Buffers、Cache、Slab这几个指标不容易 理解,我们就继续往上查找proc文件系统,获取它们的定义。

/proc 是 Linux 内核提供的一种特殊文件系统,是用户跟内核交互的接口。比方说,用户可以从 /proc 中查询内核的运行状态和配置选项,查询进程的运行状态、统计数据等,当然,你也可以通过 /proc 来修改内核的配置。

执行man proc来查看文档

如果man proc时候报错:

No manual entry for proc

先yum 安装一下man-pages 包

yum install -y man-pages
然后继续执行man proc (文档很大,可以查找meminfo)

                  Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB or so).
           Cached %lu
                  In-memory cache for files read from the disk (the page cache).  Doesn't include SwapCached.
           Slab %lu
                  In-kernel data structures cache.

通过文档我们看到


Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。

Slab  内核的数据结构缓存

这里我们可以清楚地看到三个指标的定义了。

但是在定义里没有说明Buffers是读还是写的临时存储,Cached定义中说是磁盘读取文件的缓存,是否可以写文件缓存呢?

网上有很多文章,都写Buffers是磁盘块的写缓存。

为了弄清楚这两个问题,可以用两个场景来说明展示。

首先,为了减少缓存的影响,先清理系统缓存。


#  echo 3 > /proc/sys/vm/drop_caches

场景1:文件读写案例

先在一个终端那里执行vmstat命令

每隔1秒输出1组数据

vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
2  0      0  77068  60624 496172    0    0     1     6    0    0  1  0 99  0  0
0  0      0  77068  60624 496152    0    0     0     0  573 1363  1  1 98  0  0

输出界面里, 内存部分的 buff 和 cache ,以及 io 部分的 bi 和 bo 是我们要关注的重点。

buff 和 cache 就是我们前面看到的 Buffers 和 Cache,单位是 KB。

bi 和 bo 则分别表示块设备读取和写入的大小,单位为块 / 秒。

因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。

正常情况下,空闲系统中这几个值在多次结果中一直保持不变。

然后再开一个终端,执行dd命令,生成一个文件。

dd if=/dev/urandom of=/tmp/test-file bs=1M count=500
然后回到第一个终端,看数据变化

r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0      0 515284   3828 114548    0    0     0     0  585 1365  2  1 97  0  0
0  0      0 515284   3828 114548    0    0     0     0  541 1317  1  0 99  0  0
14  0      0 506856   3832 121800    0    0    80     0 1211  878  0 71 28  1  0
12  0      0 495600   3840 133056    0    0     0   148 1334  652  0 100  0  0  0
11  0      0 484344   3840 144296    0    0     0     0 1388  684  1 99  0  0  0
13  0      0 475196   3840 153512    0    0     0     0 1254  623  0 100  0  0  0
14  0      0 463752   3840 164824    0    0     0 20520 1408  667  0 100  0  0  0
12  0      0 453612   3840 175080    0    0     0     0 1414  681  1 99  0  0  0
.
.
.
7  0      0 116636   3912 512012    0    0     4 20520 1150  639  1 99  0  0  0
10  0      0 105104   3912 523564    0    0     0     0 1436  689  0 100  0  0  0
2  0      0  95648   3912 533052    0    0     0 46080 1257  633  1 99  0  0  0
6  0      0  83992   3912 544620    0    0     0     0 1445  703  0 100  0  0  0
5  0      0  72460   3912 556172    0    0     0     0 1435  692  0 100  0  0  0
4  1      0  74980   2700 554852    0    0     0    28 1434  714  1 99  0  0  0
9  0      0  64468   2704 565300    0    0     4 20512 1465  721  0 100  0  0  0

通过vmstat的输出,在dd命令执行时,Cache在不停增长,而Buffer基本保持不变

进一步观察 I/O 的情况,你会看到,

在 Cache 刚开始增长时,块设备 I/O 很少,bi 只出现了一次 80 KB/s,bo 则只有一次 148KB。而过一段时间后,才会出现大量的块设备写,比如 bo 变成了20520。

当 dd 命令结束后,Cache 不再增长,但块设备写还会持续一段时间,并且,多次 I/O 写的结果加起来,才是 dd 要写的 500M 的数据。

测试完文件写案例,接着测试文件读案例

现在另外一个终端中执行

vmstat 1

然后在另外一个终端上执行

echo 3 > /proc/sys/vm/drop_caches
#运行dd命令读取文件数据
$ dd if=/tmp/test-file of=/dev/null```


然后再看回终端一,观察内存和I/O的变化情况:

```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 519268   1136 107824    0    0     0     0  564 1347  0  1 99  0  0
0  0      0 519268   1144 107816    0    0     0    44  594 1395  2  1 97  0  0
2  1      0 503188   1292 124124    0    0 16428     0  626 1407  1  1 96  2  0
0  1      0 396676   1292 230572    0    0 106496     0  928 1458  4 12  0 84  0
0  1      0 290216   1292 337100    0    0 106496     0  911 1382  3 11  0 86  0
2  1      0 187668   1292 439500    0    0 102400     0  936 1406  3 13  0 84  0
0  1      0  97520   1292 529612    0    0 90112     0  876 1419  4 10  0 86  0
0  0      0  73264    384 554856    0    0 90492    16  940 1410  3 13  0 84  0
0  0      0  73268    388 554876    0    0     4   120  560 1343  2  0 98  0  0
0  0      0  73268    436 554880    0    0    48     0  604 1417  2  1 93  4  0
0  0      0  73144    436 554880    0    0     0     0  601 1441  1  1 98  0  0

观察 vmstat 的输出,会发现读取文件时(也就是 bi 大于 0 时),Buffer 保持不变,而 Cache 则在不停增长。这跟查到的定义“Cache 是对文件读的页缓存”是一致的。

从这两个案例中可以看到, Cache 是文件数据的缓存,既会用在读请求中,也会用在写请求中。

场景2:磁盘的读写案例

对磁盘的写,这个案例要求比较高,需要你的系统配置多块硬盘,并且磁盘分区还要处于未使用状态。因为会损坏磁盘分区。

echo 3 > /proc/sys/vm/drop_caches
# 然后运行dd命令向磁盘分区/dev/sdb4写入2G数据
$ dd if=/dev/urandom of=/dev/sdb4 bs=1M count=2048```
然后回到另外一个终端查看vmstat的状态



```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 3644696     24  52524    0    0     0     0   85  117  0  0 100  0  0
0  0      0 3644696     24  52524    0    0     0     0   77  103  0  0 100  0  0
1  0      0 3589948  52236  54736    0    0  1380     4  787  430  0 19 81  1  0
1  0      0 3452192 186380  58204    0    0    32     0 1720  603  1 50 50  0  0
1  0      0 3354724 281520  60720    0    0     0     0 1688  606  0 50 50  0  0
3  0      0 3277440 356692  62708    0    0     0 49156 1684  613  0 60 40  0  0
1  0      0 3213408 418828  64536    0    0     0 57340 1441  431  0 62 38  0  0
1  0      0 3160660 470288  65956    0    0     0 53248 1619  569  0 60 40  0  0
1  0      0 3109140 520204  67284    0    0     0 53248 1664  544  0 62 38  0  0
1  0      0 3057880 570380  68724    0    0     0 53248 1603  535  0 61 39  0  0
4  0      0 3007020 619612  69844    0    0     0 52412 1535  509  0 62 38  0  0
2  0      0 2974628 651344  70772    0    0     0   836 1560  603  0 42 58  0  0
.
.
.
2  0      0 1874952 1720932 100704    0    0     0 95744  915  213  1 99  0  0  0
1  0      0 1817940 1776680 102172    0    0     0 20076 1673  578  0 56 44  0  0
1  0      0 1744752 1847768 104128    0    0    64     0 1427  583  0 50 50  0  0
1  0      0 1679988 1910920 105908    0    0     0     0 1416  563  0 50 50  0  0
1  0      0 1610388 1978380 107892    0    0     0     0 1468  717  0 50 50  0  0
1  0      0 1539548 2047420 109856    0    0     0     0 1380  754  0 51 50  0  0
1  0      0 1498824 2086924 110888    0    0     0 53248 1245  454  0 65 35  0  0
0  0      0 1487560 2097680 111484    0    0  1000     0  375  292  0  9 91  0  0
0  0      0 1487744 2097680 111524    0    0     0     0   99  145  0  1 100  0  0

虽然同时写数据,写磁盘跟写文件的现象还是有不同。写磁盘时(也就是bo大于0时),Buffer跟Cache都在增长,但Buffer的增长更快。

这说明,写磁盘用到了大量的 Buffer,这跟在文档中查到的定义是一样的。

案例2:读磁盘数据

echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件
$ dd if=/dev/sdb4 of=/dev/null bs=1M count=1024```
回到另外一个终端,观察vmstat中的变化:

```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 3642184     24  54120    0    0     0     0   36   54  0  1 100  0  0
0  0      0 3642184     24  54120    0    0     0     0   82  164  0  1 99  0  0
0  0      0 3642184     24  54120    0    0     0     0   65  108  0  0 100  0  0
0  0      0 3642184     24  54120    0    0     0     0   40   51  0  1 100  0  0
1  0      0 2891516 749588  54860    0    0 749564     0 3329  371  0 40 60  0  0
0  0      0 2588152 1052692  55528    0    0 303104     0 1358   65  1 18 82  0  0
0  0      0 2588152 1052692  55528    0    0     0     0   29   43  0  0 100  0  0
0  0      0 2588152 1052692  55528    0    0     0     0   28   40  0  0 100  0  0
1  0      0 2588152 1052692  55528    0    0     0     0   31   45  0  0 100  0  0
2  0      0 2588096 1052692  55528    0    0     0     0   48   59  0  0 100  0  0
0  0      0 2588152 1052692  55528    0    0     0     0   35   45  0  1 99  0  0
0  0      0 2588152 1052692  55528    0    0     0     0   23   36  0  0 100  0  0
0  0      0 2588152 1052692  55528    0    0     0     0   32   43  0  0 100  0  0

观察 vmstat 的输出,会发现读磁盘时(也就是 bi 大于 0 时),Buffer 和 Cache 都在增长,但显然 Buffer 的增长快很多。这说明读磁盘时,数据缓存到了 Buffer 中。

所以可以得到总结:Buffer对磁盘数据的缓存,既会用在读请求中,也会用在写请求中。

ps:

测试完磁盘的读写后,磁盘分区

Filesystem               Size  Used Avail Use% Mounted on
/dev/sdb4                4.8G   20M  4.6G   1% /data 

变成了这样

Filesystem               Size  Used Avail Use% Mounted on
/dev/sdb4                 18Z   18Z     0 100% /data

所以记得用空闲的磁盘分区来做测试。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容