一、free数据的来源

1、碰到看不明白的指标时该怎么办吗?

不懂就去查手册。用 man 命令查询 free 的文档、就可以找到对应指标的详细说明。比如,我们执行 man fre...

2、free数据的来源

[root@ccb-installment-api ~]# man free
NAME
free - Display amount of free and used memory in the system SYNOPSIS
free [options] DESCRIPTION
free displays the total amount of free and used physical and swap memory in the system, as well as the buffers and caches used by the kernel. The information is
gathered by parsing /proc/meminfo. The displayed columns are:
total Total installed memory (MemTotal and SwapTotal in /proc/meminfo)
used Used memory (calculated as total - free - buffers - cache)
free Unused memory (MemFree and SwapFree in /proc/meminfo)
shared Memory used (mostly) by tmpfs (Shmem in /proc/meminfo, available on kernels 2.6.32, displayed as zero if not available)
buffers
Memory used by kernel buffers (Buffers in /proc/meminfo)
cache Memory used by the page cache and slabs (Cached and Slab in /proc/meminfo)
buff/cache

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

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

3、关于磁盘和文件的区别

本来以为大家都懂了,所以没有细讲。磁盘是一个块设备,可以划分为不同的分区;在分区之上再创建文件系统,挂载到某个目录,之后才可以在这个目录中读写文件。

其实 Linux 中“一切皆文件”,而文章中提到的“文件”是普通文件,磁盘是块设备文件,这些大家可以执行 "ls -l <路径>" 查看它们的区别(输出的含义如果不懂请 man ls 查询)。

在读写普通文件时,会经过文件系统,由文件系统负责与磁盘交互;而读写磁盘或者分区时,就会跳过文件系统,也就是所谓的“裸I/O“。这两种读写方式所使用的缓存是不同的,也就是文中所讲的 Cache 和 Buffer 区别。

关于文件系统、磁盘以及 I/O 的原理,大家不要着急,后面 I/O 模块还会讲的。

二、proc文件系统

1、proc文件系统介绍

1、我在前面 CPU 性能模块就曾经提到过/proc 是 Linux 内核提供的一种特殊文件系统,是用户跟内核交互的接口比方说,用户可以从 /proc 中查询内核的运行状态和配置选项,查询进程的运行状

态、统计数据等,

2、当然,你也可以通过/proc 来修改内核的配置

3、proc文件系统同时也是很多性能工具的最终数据来源,比如我们刚看到的free,就是通过读取/proc/meminfo ,得到内存的使用情况。

2、man proc

继续说回 /proc/meminfo,既然 Buffers、Cached、SReclaimable 这几个指标不容易理解,那我们还得继续查 proc 文件系统,获取它们的详细定义。

执行 man proc ,你就可以得到 proc 文件系统的详细文档

Buffers %lu
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.
...
SReclaimable %lu (since Linux 2.6.19)
Part of Slab, that might be reclaimed, such as caches. SUnreclaim %lu (since Linux 2.6.19)
Part of Slab, that cannot be reclaimed on memory pressure.

Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB左右),这样,内核就可以把分散的写集中起来

统一优化磁盘的写入,比如可以把多次小的写合并成单词大的写等等

Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,

而不需要再次访问缓慢的磁盘。

SReclaimable 是 Slab 的一部分。Slab包括两部分,其中的可回收部分,用 SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。

3、你真的理解Buffer 和 Cache吗?

第一个问题:Buffer 的文档没有提到这是磁盘读数据还是写数据的缓存,而在很多网络搜索的结果中都会提到 Buffer 只是对将要写入磁盘数据的缓存。那反过来说,

它会不会也缓存从磁盘中读取的数据呢?

第二个问题:文档中提到,Cache 是对从文件读取数据的缓存,那么它是不是也会缓存写文件的数据呢?

简单来说,Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。

三、磁盘和文件写案例

1、磁盘写案例

1、清理缓存

# 清理文件页、目录项、Inodes 等各种缓存
$ echo 3 > /proc/sys/vm/drop_caches

2、终端一运行vmstat

[root@luoahong ~]# 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 7544944 0 151620 0 0 976 176 347 585 4 12 83 1 0
0 0 0 7544944 0 151636 0 0 0 0 100 145 0 0 100 0 0
0 0 0 7544944 0 151636 0 0 0 0 109 156 0 0 100 0 0
0 0 0 7544944 0 151636 0 0 0 0 104 154 0 0 100 0 0
0 0 0 7544944 0 151636 0 0 0 0 113 153 0 0 100 0 0

正常情况下,空闲系统中,你应该看到的是,这几个值在多次结果中一直保持不变。

3、终端2执行 dd 命令,通过读取随机设备,生成一个 500MB 大小的文件

dd if=/dev/urandom of=/tmp/file bs=1M count=500

4、第一个终端,观察 Buffer 和 Cache 的变化情况

[root@luoahong ~]# 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
4 0 0 7270684 0 424228 0 0 708 128 283 453 3 10 87 1 0
1 0 0 7213892 0 480700 0 0 0 0 2022 742 0 51 49 0 0
1 0 0 7161068 0 533556 0 0 0 0 1846 734 0 51 49 0 0
1 0 0 7109112 0 585616 0 0 0 0 2014 733 0 51 49 0 0
1 0 0 7058272 0 636312 0 0 0 0 1874 734 0 50 50 0 0
0 0 0 7018616 0 676764 0 0 20 0 1511 590 0 38 62 0 0
0 0 0 7018616 0 676764 0 0 0 0 103 145 0 0 100 0 0
4 0 0 7017232 0 677820 0 0 9 159744 514 188 0 10 87 3 0
0 0 0 7018288 0 676844 0 0 0 0 211 189 0 2 98 0 0
0 0 0 7018288 0 676844 0 0 0 0 122 151 0 0 100 0 0
0 0 0 7018288 0 676844 0 0 0 0 139 176 1 1 98 1 0
0 0 0 7018288 0 676844 0 0 0 0 98 137 0 0 100 0 0
1 0 0 7018288 0 676844 0 0 0 13312 171 175 0 2 98 0 0
0 0 0 7018448 0 676684 0 0 0 338944 906 257 0 17 83 0 0
0 0 0 7018448 0 676684 0 0 0 0 106 148 0 0 100 0 0
0 0 0 7018448 0 676684 0 0 0 0 100 141 0 1 99 0 0
...

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

bi 和 bo 则分别表示块设备读取和写入的大小,单位为块因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。

1、Cache 在不停地增长,而 Buffer 基本保持不变。

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

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

2、文件写案例

1、清理缓存

# 清理文件页、目录项、Inodes 等各种缓存
$ echo 3 > /proc/sys/vm/drop_caches

2、终端一运行vmstat

[root@luoahong ~]# 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
1 0 0 7006732 4 682672 0 0 159 301 100 152 1 3 97 0 0
0 0 0 7006740 4 682672 0 0 0 0 84 127 0 0 100 0 0
0 0 0 7006740 4 682672 0 0 16 43 61 105 0 0 100 0 0
0 0 0 7006740 4 682672 0 0 0 0 61 119 0 0 100 0 0

3、终端2向磁盘分区 /dev/sdb1 写入 2GB 的随机数据

dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048

4、第一个终端,观察 Buffer 和 Cache 的变化情况

[root@luoahong ~]# 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 6977304 534528 179348 0 0 154 286 100 148 1 3 97 0 0
2 0 0 6904740 603176 182796 0 0 0 53248 1972 633 0 60 40 0 0
1 0 0 6845544 659456 185888 0 0 0 0 1058 126 0 50 50 0 0
1 0 0 6787756 714328 188876 0 0 0 0 1102 216 0 50 50 0 0
1 0 0 6731240 768000 191680 0 0 0 0 1352 713 0 51 49 0 0
1 0 0 6675808 820568 194512 0 0 0 53248 1600 616 0 56 44 0 0
3 0 0 6622872 870884 197056 0 0 0 278274 2679 151 0 79 21 0 0
3 0 0 6574708 916448 199632 0 0 0 501504 3947 180 0 100 0 0 0
1 0 0 6517416 970824 202640 0 0 0 31230 1217 97 0 53 47 0 0
1 0 0 6459256 1026048 205516 0 0 0 0 1033 89 0 50 50 0 0
1 0 0 6401220 1081212 208592 0 0 0 0 1034 78 0 50 50 0 0
1 0 0 6343588 1135928 211524 0 0 0 0 1045 103 0 50 50 0 0
1 0 0 6286420 1190236 214284 0 0 0 0 1359 740 0 51 49 0 0
1 0 0 6234832 1239040 216988 0 0 0 304872 2838 299 0 81 19 0 0
1 0 0 6177044 1294048 219956 0 0 0 1 1041 86 0 50 50 0 0
1 0 0 6119380 1348628 222920 0 0 0 0 1030 81 0 50 50 0 0
1 0 0 6061128 1403904 225876 0 0 0 0 1034 78 0 50 50 0 0
3 0 0 6023576 1439248 227952 0 0 360 215042 2618 668 0 59 41 0 0
0 0 0 7539344 0 151992 0 0 1086 1828 418 302 1 11 88 0 0
0 0 0 7539372 0 152032 0 0 0 4 117 139 1 1 99 0 0
0 0 0 7539372 0 152032 0 0 0 0 57 88 0 0 100 0 0
0 0 0 7539248 0 152032 0 0 40 0 96 123 0 1 99 0 0

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

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

写文件时会用到 Cache 缓存数据,而写磁盘则会用到Buffer 来缓存数据。所以,回到刚刚的问题,虽然文档上只提到,Cache 是文件读的缓存,但实际上,Cache 也会缓存写文件时的数据。

四、磁盘和文件读案例

1、磁盘写案例

1、清理缓存

# 清理文件页、目录项、Inodes 等各种缓存
$ echo 3 > /proc/sys/vm/drop_caches

2、终端一运行vmstat

[root@luoahong ~]# 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 7539868 0 151596 0 0 126 820 96 130 0 3 96 0 0
0 0 0 7539908 0 151636 0 0 0 0 49 94 0 1 99 1 0
0 0 0 7539908 0 151636 0 0 0 0 61 105 0 0 100 0 0
0 0 0 7539908 0 151636 0 0 0 0 58 95 0 0 100 0 0

3、终端2从文件 /tmp/file 中,读取数据写入空设备

dd if=/tmp/file of=/dev/null

4、第一个终端,观察 Buffer 和 Cache 的变化情况

[root@luoahong ~]# 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
3 0 0 7237960 0 454648 0 0 245 803 96 128 0 3 96 0 0
1 0 0 7164180 0 528288 0 0 72704 0 1193 141 0 50 50 0 0
1 0 0 7090400 0 602004 0 0 73728 0 1063 73 0 52 48 0 0
0 0 0 7029028 0 663684 0 0 61616 0 1763 573 0 52 48 0 0
0 0 0 7029044 0 663684 0 0 0 0 65 101 1 0 99 0 0

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

2、文件写案例

1、清理缓存

# 清理文件页、目录项、Inodes 等各种缓存
$ echo 3 > /proc/sys/vm/drop_caches

2、终端一运行vmstat

 [root@luoahong ~]# 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
1 0 0 7541212 0 151572 0 0 296 720 90 121 0 3 97 0 0
0 0 0 7541212 0 151576 0 0 0 0 54 108 0 0 100 0 0
0 0 0 7541212 0 151576 0 0 0 0 45 79 0 0 100 0 0
0 0 0 7541212 0 151576 0 0 0 0 54 94 0 1 100 0 0

3、终端2从磁盘分区 /dev/sda1 中读取数据,写入空设备

dd if=/tmp/file of=/dev/null

4、第一个终端,观察 Buffer 和 Cache 的变化情况

[root@luoahong ~]# 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
1 0 0 7540956 0 151576 0 0 287 698 88 118 0 3 97 0 0
0 0 0 7540956 0 151584 0 0 0 0 88 139 0 0 100 0 0
0 0 0 7540956 0 151584 0 0 0 0 85 136 0 0 100 0 0
1 0 0 6869864 667140 151900 0 0 669772 0 1343 207 0 36 64 0 0
0 0 0 6484500 1054720 152876 0 0 385024 0 742 332 0 15 85 0 0
0 0 0 6484500 1054720 152876 0 0 0 0 134 214 1 0 99 0 0
0 0 0 6484500 1054720 152876 0 0 0 0 78 141 0 1 99 1 0
0 0 0 6484500 1054720 152876 0 0 0 0 112 205 0 0 100 0 0
0 0 0 6484500 1054720 152876 0 0 0 0 106 168 0 0 100 0 0
0 0 0 6484500 1054720 152876 0 0 0 0 67 121 0 1 100 0 0

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

Buffer 既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”

Cache 既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。

这样,我们就回答了案例开始前的两个问题。

简单来说,Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。

Linux性能优化实战学习笔记:第十六讲的更多相关文章

  1. Linux性能优化实战学习笔记:第六讲

    一.环境准备 1.安装软件包 终端1 机器配置:2 CPU,8GB 内存 预先安装 docker.sysstat.perf等工具 [root@luoahong ~]# docker -v Docker ...

  2. Linux性能优化实战学习笔记:第六讲1

    一.环境准备 1.安装软件包 终端1 机器配置:2 CPU,8GB 内存 预先安装 docker.sysstat.perf等工具 [root@luoahong ~]# docker -v Docker ...

  3. Linux性能优化实战学习笔记:第十七讲

    一.缓存命中率 1.引子 1.我们想利用缓存来提升程序的运行效率,应该怎么评估这个效果呢? 用衡量缓存好坏的指标 2.有没有哪个指标可以衡量缓存使用的好坏呢? 缓存命中率 3.什么是缓存命中率? 所谓 ...

  4. Linux性能优化实战学习笔记:第四讲

    一.怎么查看系统上下文切换情况 通过前面学习我么你知道,过多的上下文切换,会把CPU时间消耗在寄存器.内核栈以及虚拟内存等数据的保存和回复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶 既 ...

  5. Linux性能优化实战学习笔记:第二十七讲

    一.案例环境描述 1.环境准备 2CPU,4GB内存 预先安装docker sysstat工具 2.温馨提示 案例中 Python 应用的核心逻辑比较简单,你可能一眼就能看出问题,但实际生产环境中的源 ...

  6. Linux性能优化实战学习笔记:第七讲

    一.进程的状态 1.命令查看 top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28961 root 20 0 43816 3148 ...

  7. Linux性能优化实战学习笔记:第二十一讲

    一 内存性能指标 1.系统内存使用情况 共享内存:是通过tmpfs实现的,所以它的大小也就是tmpfs使用的大小了tmpfs其实也是一种特殊的缓存 可用内存:是新进程可以使用的最大内存它包括剩余内存和 ...

  8. Linux性能优化实战学习笔记:第八讲

    一.环境准备 1.在第6节的基础上安装dstat wget http://mirror.centos.org/centos/7/os/x86_64/Packages/dstat-0.7.2-12.el ...

  9. Linux性能优化实战学习笔记:第十一讲

    一.性能指标 1.性能指标思维导图 2.CPU使用率 3.CPU平均负载 4.CPU缓存的命中率 CPU 在访问内存的时候,免不了要等待内存的响应.为了协调这两者巨大的性能差距,CPU 缓存(通常是多 ...

  10. Linux性能优化实战学习笔记:第四十五讲

    一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...

随机推荐

  1. LeetCode 739:每日温度 Daily Temperatures

    题目: 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperature ...

  2. AngleSharp 实战(01)之最简单的示例

    文档地址:https://anglesharp.github.io/docs/Examples.html 直接贴代码了: using System; using System.Linq; using ...

  3. JVM的监控工具之jvisual

    VisualVM(All-in-One Java Trouble shootingTool)是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序,并且可以预见在未来一段时间内都是官方主力发展的 ...

  4. 『大 树形dp』

    大 Description 滑稽树上滑稽果,滑稽树下你和我,滑稽树前做游戏,滑稽多又多.树上有 n 个节点,它们构成了一棵树,每个节点都有一个滑稽值. 一个大的连通块是指其中最大滑稽值和最小滑稽值之差 ...

  5. python numba讲解

    目录 一:什么是numba 二:如何使用numba   由于python有动态解释性语言的特性,跑起代码来相比java.c++要慢很多,尤其在做科学计算的时候,十亿百亿级别的运算,让python的这种 ...

  6. CentOS7 vsftp 安装与配置(视频教程)

    (双击全屏播放) 1.安装vsftpd yum install -y vsftpd 2.编辑ftp配置文件 vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO ...

  7. JavaScript 数据类型转换表

    下表显示了将不同的JavaScript值转换为Number,String和Boolean的结果: 原始值 转换为Number 转换为String 转换为Boolean false 0 "fa ...

  8. 表单验证如何让select设置为必选

    <select class="custom-select mr-sm-2" name="province" id="province" ...

  9. Docker制作dotnet core控制台程序镜像

    (1)首先我们到某个目录下,然后在此目录下打开visual studio code. 2.编辑docker file文件如下: 3.使用dotnet new console创建控制台程序; 4.使用d ...

  10. 绕过基于签名的XSS筛选器:修改HTML

    绕过基于签名的XSS筛选器:修改HTML 在很多情况下,您可能会发现基于签名的过滤器只需切换到一个不太熟悉的执行脚本的方法即可.如果失败了,您需要查看混淆攻击的方法. 本文提供了HTML语法可以被混淆 ...