Linux性能优化实战
倪朋飞
微软资深工程师,Kubernetes项目维护者
立即订阅
23395 人已学习
课程目录
已完结 64 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词 | 别再让Linux性能问题成为你的绊脚石
免费
01 | 如何学习Linux性能优化?
CPU 性能篇 (13讲)
02 | 基础篇:到底应该怎么理解“平均负载”?
03 | 基础篇:经常说的 CPU 上下文切换是什么意思?(上)
04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)
05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)
08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)
09 | 基础篇:怎么理解Linux软中断?
10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
12 | 套路篇:CPU 性能优化的几个思路
13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
14 | 答疑(二):如何用perf工具分析Java程序?
内存性能篇 (8讲)
15 | 基础篇:Linux内存是怎么工作的?
16 | 基础篇:怎么理解内存中的Buffer和Cache?
17 | 案例篇:如何利用系统缓存优化程序的运行效率?
18 | 案例篇:内存泄漏了,我该如何定位和处理?
19 | 案例篇:为什么系统的Swap变高了(上)
20 | 案例篇:为什么系统的Swap变高了?(下)
21 | 套路篇:如何“快准狠”找到系统内存的问题?
22 | 答疑(三):文件系统与磁盘的区别是什么?
I/O 性能篇 (10讲)
23 | 基础篇:Linux 文件系统是怎么工作的?
24 | 基础篇:Linux 磁盘I/O是怎么工作的(上)
25 | 基础篇:Linux 磁盘I/O是怎么工作的(下)
26 | 案例篇:如何找出狂打日志的“内鬼”?
27 | 案例篇:为什么我的磁盘I/O延迟很高?
28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
29 | 案例篇:Redis响应严重延迟,如何解决?
30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
31 | 套路篇:磁盘 I/O 性能优化的几个思路
32 | 答疑(四):阻塞、非阻塞 I/O 与同步、异步 I/O 的区别和联系
网络性能篇 (13讲)
33 | 关于 Linux 网络,你必须知道这些(上)
34 | 关于 Linux 网络,你必须知道这些(下)
35 | 基础篇:C10K 和 C1000K 回顾
36 | 套路篇:怎么评估系统的网络性能?
37 | 案例篇:DNS 解析时快时慢,我该怎么办?
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
40 | 案例篇:网络请求延迟变大了,我该怎么办?
41 | 案例篇:如何优化 NAT 性能?(上)
42 | 案例篇:如何优化 NAT 性能?(下)
43 | 套路篇:网络性能优化的几个思路(上)
44 | 套路篇:网络性能优化的几个思路(下)
45 | 答疑(五):网络收发过程中,缓冲区位置在哪里?
综合实战篇 (13讲)
46 | 案例篇:为什么应用容器化后,启动慢了很多?
47 | 案例篇:服务器总是时不时丢包,我该怎么办?(上)
48 | 案例篇:服务器总是时不时丢包,我该怎么办?(下)
49 | 案例篇:内核线程 CPU 利用率太高,我该怎么办?
50 | 案例篇:动态追踪怎么用?(上)
51 | 案例篇:动态追踪怎么用?(下)
52 | 案例篇:服务吞吐量下降很厉害,怎么分析?
53 | 套路篇:系统监控的综合思路
54 | 套路篇:应用监控的一般思路
55 | 套路篇:分析性能问题的一般步骤
56 | 套路篇:优化性能问题的一般方法
57 | 套路篇:Linux 性能工具速查
58 | 答疑(六):容器冷启动如何性能分析?
加餐篇 (4讲)
加餐(一) | 书单推荐:性能优化和Linux 系统原理
加餐(二) | 书单推荐:网络原理和 Linux 内核实现
用户故事 | “半路出家 ”,也要顺利拿下性能优化!
用户故事 | 运维和开发工程师们怎么说?
结束语 (1讲)
结束语 | 愿你攻克性能难关
Linux性能优化实战
登录|注册

16 | 基础篇:怎么理解内存中的Buffer和Cache?

倪朋飞 2018-12-26
你好,我是倪朋飞。
上一节,我们梳理了 Linux 内存管理的基本原理,并学会了用 free 和 top 等工具,来查看系统和进程的内存使用情况。
内存和 CPU 的关系非常紧密,而内存管理本身也是很复杂的机制,所以感觉知识很硬核、很难啃,都是正常的。但还是那句话,初学时不用非得理解所有内容,继续往后学,多理解相关的概念并配合一定的实践之后,再回头复习往往会容易不少。当然,基本功不容放弃。
在今天的内容开始之前,我们先来回顾一下系统的内存使用情况,比如下面这个 free 输出界面:
# 注意不同版本的free输出可能会有所不同
$ free
total used free shared buff/cache available
Mem: 8169348 263524 6875352 668 1030472 7611064
Swap: 0 0 0
显然,这个界面包含了物理内存 Mem 和交换分区 Swap 的具体使用情况,比如总内存、已用内存、缓存、可用内存等。其中缓存是 Buffer 和 Cache 两部分的总和 。
这里的大部分指标都比较容易理解,但 Buffer 和 Cache 可能不太好区分。从字面上来说,Buffer 是缓冲区,而 Cache 是缓存,两者都是数据在内存中的临时存储。那么,你知道这两种“临时存储”有什么区别吗?
注:今天内容接下来的部分,Buffer 和 Cache 我会都用英文来表示,避免跟文中的“缓存”一词混淆。而文中的“缓存”,则通指内存中的临时存储。

free 数据的来源

取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(94)

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

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

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

    关于文件系统、磁盘以及 I/O 的原理,大家不要着急,后面 I/O 模块还会讲的。
    2018-12-26
    161
  • Geek_5258f8
    理论上,一个文件读首先到Block Buffer, 然后到Page Cache。有了文件系统才有了Page Cache.
    在老的Linux上这两个Cache是分开的。那这样对于文件数据,会被Cache两次。这种方案虽然简单,
    但低效。后期Linux把这两个Cache统一了。对于文件,Page Cache指向Block Buffer,对于非文件
    则是Block Buffer。这样就如文件实验的结果,文件操作,只影响Page Cache,Raw操作,则只影响Buffer. 比如一此VM虚拟机,则会越过File System,只接操作 Disk, 常说的Direct IO.

    作者回复: 👍

    2018-12-26
    3
    67
  • JJ
    还是有点困惑,感觉读写磁盘上的数据不就是读写磁盘上的文件里的数据嘛,难道读磁盘上的数据可以不经过文件系统吗,可以直接读裸磁盘?有点没理解buffer是磁盘上的数据缓存,cache是文件数据缓存,求大神解答下。。

    作者回复: 请参考置顶回复

    2018-12-26
    12
  • Dr. ZZZ
    老师,关于buffer是对直接写磁盘的缓存,我想问下。现实中有哪些是直接写磁盘的场景。写读写文件不也最终是写到磁盘上吗?谢谢
    2019-01-01
    1
    6
  • David.cui
    数据库使用裸设备是明显的磁盘读写;如果数据库的数据文件在文件系统上就是文件读写。这样理解对么

    作者回复: 对的

    2018-12-26
    5
  • acm1204
    socket buffer属于哪一类?

    作者回复: cache

    2019-04-08
    3
  • Mr.Strive.Z.H.L
    老师您好,有一个疑惑:
    数据写入到page cache。后续应用程序强制刷盘或者系统自动刷盘的时候,page cache中的数据还会经过buffer,然后再到块设备吗?还是不会经过buffer,直接刷到块设备了?
    (读取比较好理解,读取文件直接到page cache,读取块设备先到buffer,buffer不够再到page cache)

    作者回复: 早期的Linux会的,也就是cache两次。不过现在不会了,只会经过一层cache。

    2019-01-22
    3
  • 虎虎❤️

    通过读csapp,又复习了下虚拟内存。其概念为 “虚拟内存组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。” 访问虚拟内存时,MMU通过访问页表,来索引到实际的存储地址。如果在物理内存中有缓存,直接从物理内存中读取数据。否则,从磁盘中读取,并选择牺牲一个物理页,并替换为新读取的页(当然,我觉得这种应该是在内存没有free的情况下)。如果被牺牲的页发生改变,则写回磁盘。最后更新页表。

    我的问题是:
    1. 上一节讲了虚拟内存的空间分布,那么物理内存有没有空间分布的概念?从vmstat的输出来看,物理内存是不是只包括buffer cache 和 free呢?
    2. 这里的cache是不是等同于虚拟内存在物理内存中的缓存?
    3. 上一节课所说的内存回收。使用LRU算法“回收缓存”,是否是我上面描述的概念?那么所谓的“回收不常访问的内存,把不常用的内存通过交换分区直接写到磁盘中”,指的是交换出哪种内存?cache?buffer?或者其他的种类?

    希望得到老师回复,也欢迎各位大佬共同探讨。

    作者回复: 1. 物理内存的分布由系统管理,没有类似于虚拟内存这样的分布
    2. 不是
    3. LRU回收的是缓存,Swap换出的是不可回收的内存,比如进程的堆内存

    2018-12-26
    3
  • croco
    我好像明白了,就是/proc/<pid>/smaps中的Pss相加,因为Pss是私有内存+共享内存按比例属于自己计算的那一部分
    比如私有内存是200k, 共享内存500k和4个其它进程共享,那么是Pss就是200k+(500/(1+4))=200k+100k=300k。 这样所有进程的Pss相加就不会有重复相加的顾虑,因为Pss中已经将共享内存部分帮我们算好了
    参考命令:awk '/Pss:/{ sum += $2 } END { print sum }' /proc/$$/smaps

    作者回复: 嗯嗯

    2019-06-13
    2
  • 吴林辉
    “因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。”关于这一点,想请问下老师,linux block的大小不是4KB呢?

    作者回复: 这句话来自vmstat的文档:https://linux.die.net/man/8/vmstat

    通常说的的 Block Size 是磁盘分区的块大小,的确都是 4KB 了。

    2019-02-18
    2
  • 无名老卒
    看了这篇文章,终于理解 了buffers以及cache,之前在网上还专门查过这2者的区别,但就是像老师说的那样,文章看下来,啥也没有啥明白。

    按照老师的总结,cache是针对文件系统的缓存 ,而buffers是对磁盘数据的缓存,是直接跟硬件那一层相关的,那一般来说,cache会比buffers的数量大了很多。生产环境下面看了多台机器,的确如此。

    后面留的那个作业,如果要统计一个进程所占用的物理空间,我的做法是累加RSS的值。如下shell是我工作中所使用的命令,取内存占用top10的进程:

    for i in $( ls /proc/ |grep "^[0-9]"|awk '$0 >100') ;do cmd="";[ -f /proc/$i/cmdline ] && cmd=`cat /proc/$i/cmdline`;[ "$cmd"X = ""X ] && cmd=$i;awk -v i="$cmd" '/Rss:/{a=a+$2}END{printf("%s:%d\n",i,a)}' /proc/$i/smaps 2>/dev/null; done | sort -t: -k2nr | head -10

    作者回复: 总结的不错,不过计算方法还是不太准确。可以继续查一下PSS和PSS的区别

    2018-12-27
    1
    2
  • 某、人
    老师,是否绕开文件系统,直接对磁盘进行读写会更快呢?

    作者回复: 去掉缓存的话,文件系统比磁盘又多了一层,所以有可能比直接磁盘读写慢。但文件系统也有缓存,所以大部分情况下不绕开会更快

    2018-12-26
    2
  • 我来也
    [D16打卡]
    只有一块磁盘,就没轻易的试第二个案例.
    ---------------------------------------------------
    以前应该只接触到了文件数据的缓存cache,没接触到磁盘数据的缓存buffer.
    1.vim一个大文件,在第一次加载时较慢,之后再次打开时,会明显感觉到加载速度更快,应该就是cache的功劳.
    2.在linux下写c程序时,打印日志printf后面习惯加fflush(stdout);
    可以强制刷新缓冲区的内容到物理设备.在程序宕掉时可以定位到最后的输出日志.
    如果不加fflush,可能会丢失掉部分缓冲区内的日志.
    不知道这里的缓冲区跟系统的cache是不是一个概念.
    ---------------------------------------------------
    ls -l 磁盘与普通文件的区别:
    # ls -l /dev/sda1
    brw-rw---- 1 root disk 8, 1 12月 12 10:17 /dev/sda1
    # ls -ld /root/
    drwx------ 12 root root 4096 12月 26 11:48 /root/
    第一个字符b应该表示是磁盘类型 d就是目录类型了
    有一列一个显示的第几块磁盘的第几个分区[8,1],一个是占用的空间大小[4096].
    疑问:man ls 了也没看到各列具体的含义啊,这个去哪查呢?
    ---------------------------------------------------
    老师最后的问题深入探索又是一篇长文了.哈哈!

    作者回复: 前面2是C库的缓存,跟系统的缓存没关系

    ls的文档参考 info coreutils 'ls invocation'

    2018-12-26
    2
  • 科学Jia
    老师,女同学我今天上班时间终于追到这里了。写的真真清楚,想知道您花了多少时间学这些?

    作者回复: 也花了挺多时间,有些基础的原理在学校就学过了,也有很多是实践中学到的经验

    2018-12-26
    2
  • 有些细节未能理解,网上也找不到答案,望老师指点。
    1,关于写硬盘,cache也有一定程度的提升, 我自己测试写硬盘2GB,cache增长幅度为430MB,请问这部分的cache增长是什么原因呢?
    2,关于读磁盘,cache也有很轻微的增长,请问其中的原因又是?
    2019-05-21
    1
  • AI杜嘉嘉
    想请教一下老师,怎么看待一个系统buffer和cache使用率过高的问题。是好是坏,如果这些缓存没及时回收可能会导致,程序异常

    作者回复: 通常来说都是好事,不过也不是绝对的,还要看具体的场景的。比如,内存紧张的时候,回收缓存会对性能有一定影响;不合理的应用占用大量缓存,也可能会会导致内存不足。

    2019-02-21
    1
  • 爱学习的小学生
    打卡
    2019-02-20
    1
  • 小虎
    老是如果使用mmap进行写文件的话是先写入缓存,假如此时断电那么cache里面的数据会丢失吗?或者说系统怎么保证断电下cache的数据在恢复用电后还可以写入文件不丢失。

    作者回复: 有可能会丢失,所以很多应用还需要主动 sync

    2019-01-14
    1
  • 腾达
    $ dd if=/tmp/file of=/dev/null 为什么很快就结束了?导致vmstat值变化不大

    作者回复: 清缓存了吗?

    2018-12-26
    1
  • 往事随风,顺其自然
    # 首先清理缓存
    $ echo 3 > /proc/sys/vm/drop_caches
    # 然后运行 dd 命令向磁盘分区 /dev/sdb1 写入 2G 数据
    $ dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048

    这个测试,在centos下是cache比buffer增长的快,和你说ub下正好相反,这是为什么?
    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 34840 213268 172 193516 0 0 0 0 952 94 0 23 77 0 0
     1 0 34840 209176 172 197624 0 0 0 0 1044 92 0 24 76 0 0
     1 0 34840 204092 172 202740 0 0 0 0 1042 97 0 24 76 0 0
     1 0 34840 200000 180 206848 0 0 0 32 1056 97 0 25 75 0 0
     1 0 34840 194792 180 211836 0 0 0 0 1060 87 0 25 75 0 0
     1 0 34840 190700 180 216068 0 0 0 0 1006 96 0 24 76 0 0
     1 0 34840 188716 180 218092 0 0 0 0 933 93 0 23 77 0 0
     1 0 34840 184624 180 222212 0 0 0 0 1057 94 0 25 75 0 0
     1 0 34840 179540 180 227196 0 0 0 0 1082 100 0 25 75 0 0
     1 0 34840 175448 180 231428 0 0 0 0 1053 94 0 25 75 0 0
     1 0 34840 170240 180 236412 0 0 0 0 1066 92 0 25 75 0 0
     1 0 34840 166148 180 240644 0 0 0 0 1055 92 0 25 75 0 0
     1 0 34840 164164 180 242668 0 0 0 0 1021 110 0 24 76 0 0
     1 0 34840 158956 180 247812 0 0 0 0 1041 86 0 25 75 0 0
     1 0 34840 154864 180 251908 0 0 0 0 1071 94 0 25 75 0 0

    作者回复: 系统什么版本?是不是比较老?

    2018-12-26
    1
收起评论
94
返回
顶部