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性能优化实战
登录|注册

23 | 基础篇:Linux 文件系统是怎么工作的?

倪朋飞 2019-01-11
你好,我是倪朋飞。
通过前面 CPU 和内存模块的学习,我相信,你已经掌握了 CPU 和内存的性能分析以及优化思路。从这一节开始,我们将进入下一个重要模块——文件系统和磁盘的 I/O 性能。
同 CPU、内存一样,磁盘和文件系统的管理,也是操作系统最核心的功能。
磁盘为系统提供了最基本的持久化存储。
文件系统则在磁盘的基础上,提供了一个用来管理文件的树状结构。
那么,磁盘和文件系统是怎么工作的呢?又有哪些指标可以衡量它们的性能呢?
今天,我就带你先来看看,Linux 文件系统的工作原理。磁盘的工作原理,我们下一节再来学习。

索引节点和目录项

文件系统,本身是对存储设备上的文件,进行组织管理的机制。组织方式不同,就会形成不同的文件系统。
你要记住最重要的一点,在 Linux 中一切皆文件。不仅普通的文件和目录,就连块设备、套接字、管道等,也都要通过统一的文件系统来管理。
为了方便管理,Linux 文件系统为每个文件都分配两个数据结构,索引节点(index node)和目录项(directory entry)。它们主要用来记录文件的元信息和目录结构。
索引节点,简称为 inode,用来记录文件的元数据,比如 inode 编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以记住,索引节点同样占用磁盘空间。
目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不过,不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(49)

  • coyang
    课后题:
    这个命令,会不会导致系统的缓存升高呢?
    --> 会的
    如果有影响,又会导致哪种类型的缓存升高呢?
    --> /xfs_inode/ proc_inode_cache/dentry/inode_cache

    实验步骤:
    1. 清空缓存:echo 3 > /proc/sys/vm/drop_caches ; sync
    2. 执行find : find / -name test
    3. 发现更新top 4 项是:
      OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
     37400 37400 100% 0.94K 2200 17 35200K xfs_inode
     36588 36113 98% 0.64K 3049 12 24392K proc_inode_cache
    104979 104979 100% 0.19K 4999 21 19996K dentry
     18057 18057 100% 0.58K 1389 13 11112K inode_cache

    find / -name 这个命令是全盘扫描(既包括内存文件系统又包含本地的xfs【我的环境没有mount 网络文件系统】),所以 inode cache & dentry & proc inode cache 会升高。

    另外,执行过了一次后再次执行find 就机会没有变化了,执行速度也快了很多,也就是下次的find大部分是依赖cache的结果。

    作者回复: 赞

    2019-01-11
    27
  • 白华
    课后题:我找了一个目录下的文件,用的这个命令find / -type f -name copyright 然后slabtop观察,发现dentry的SLABS和SIZE有了明显的提高,所以引起了目录项缓存的升高。在开始的时候dentry有一定的大小,我认为是缓存了/目录下系统基本的目录,但是系统后面下载、创建的内容是没有缓存的,使用查找命令会把这些都查找到然后缓存起来,所以使用find查找大量内容时候会造成性能下降。

    前面看老男孩视频时候了解了inode和block。inode存储这些数据属性信息的,包含不限于文件大小、文件类型、文件权限、拥有者、硬链接数、所属组、修改时间,还包含指向文件实体的指针功能(inode节点---block的对应关系),但是inode惟独不包含文件名。文件名不在inode里,在上级目录的block里;Block来存储实际数据用的,例如照片、视频等普通文件数据。

    今天看到了dentry,定义是用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。但是和老男孩老师讲的有所区别,希望老师帮我解惑
    2019-01-11
    17
  • 石维康
    阻塞 I/O 和非阻塞 I/O的概念和同步和异步 I/O的区别是什么?

    作者回复: 这个在答疑里统一回复吧

    2019-01-11
    10
  • 伟忠
    机器上 df 查看占用了 200G,但 du 查看发现只有 90G,看网上的办法用 lsof | grep delete 查看,但没有找到,请问老师,这个可能是什么原因呢?

    作者回复: 可能是文件本身已经删除了,但其描述符还被进程占用着,可以查找无效的文件描述符看看

    2019-01-12
    6
  • 肘子哥
    有个疑惑,如果目录项存在内存中是不是意味着内存故障后,目录就无法访问了呢?

    作者回复: 不会的,还可以从磁盘的持久化数据中重建

    2019-02-23
    5
  • ThinkerWalker
    关于白华提到的: "前面看老男孩视频时候了解了inode和block。inode存储这些数据属性信息的,包含不限于文件大小、文件类型、文件权限、拥有者、硬链接数、所属组、修改时间,还包含指向文件实体的指针功能(inode节点---block的对应关系),但是inode惟独不包含文件名。文件名不在inode里,在上级目录的block里;Block来存储实际数据用的,例如照片、视频等普通文件数据。"

    我想说,目录项本质上是缓存,缓存是为了加速文件查找和访问的,所以说和老师这里所说的dentry不冲突,没有目录项的时候查找一个文件需要从/一级一级查找. 是这样的吧?倪老师?
    2019-04-16
    3
  • DJH
    请教三个问题。

    1. 目录项是维护在内核中的一个内存数据结构,包括文件名。
    我的问题是:文件名不是也应该存储在磁盘上么?不可能仅仅存在于内存吧?

    2. 缓冲 I/O,是指利用标准库缓存来减速文件的访问...
    我的问题时:减速文件访问的原因是什么?

    3. 阻塞/非阻塞与同步/非同步的区别是什么?

    作者回复: 1. 目录项是表示目录之间的树状关系,而文件名则会存储到数据部分。
    2. 不好意思,是个笔误,当然是加速。谢谢指出
    3. 这个在文章中有简单的介绍,回来在答疑篇中再展开一些

    2019-01-11
    2
  • 圣诞使者
    课后题,我感觉不会,应该只有用了目录的执行(x)权限内核才会缓存dentry,find只是用了目录的读(r)权限。
    2019-01-11
    2
  • xzyeah
    老师,我的理解,不会引起内存升高,因为文件名存在于目录项,目录项本身就存在于内存缓存。
    2019-01-11
    2
  • hola
    “索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘”
    是一对一关系吗,那么看我的服务器
    $ df -i /
    文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点
    /dev/mapper/VolGroup-lv_root 655360 98862 556498 16% /
    意思是这个下面理论最多存放655360个文件 对吗



    作者回复: 嗯

    2019-02-23
    1
  • 小成
    请问老师,除了目录项以外还有哪些地方保存有文件名,下一节讲到目录项是一个内存缓存,那么不会保存文件名到磁盘上面?

    作者回复: 目录项是一个缓存,不是持久化存储。目录也是一个文件,这个特殊文件保存了该目录的所有文件名与inode的对应关系

    2019-02-01
    1
  • 董文荣
    课后题:
    Q:$ find / -name file-name
    这个命令,会不会导致系统的缓存升高呢?如果有影响,又会导致哪种类型的缓存升高呢?
    A:分析
    1)、"/"代表文件系统的根目录,目录项已经缓存在cached。(通过下面的测试,怀疑应该只是部分目录项的内容缓存在cache中,待验证)
    2)、因为会匹配值“file-name“,会将索引节点读入缓存进行匹配。
    因此会导致cached增长。以下是三组测试对比,给出了执行find命令前后,cached变化的对比。
    命令之前前后,slabtop的执行前后对比:
    Active / Total Objects (% used) : 184412 / 240169 (76.8%)
     Active / Total Size (% used) : 42926.19K / 59199.82K (72.5%)

      OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
     11088 2313 20% 0.57K 198 56 6336K radix_tree_node
     10450 9515 91% 0.58K 190 55 6080K inode_cache
     27510 12695 46% 0.19K 655 42 5240K dentry
      4710 1003 21% 1.06K 157 30 5024K xfs_inode


     Active / Total Objects (% used) : 1795399 / 1809652 (99.2%)
     Active / Total Size (% used) : 1004316.02K / 1007573.47K (99.7%)

      OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
    708420 708420 100% 1.06K 23614 30 755648K xfs_inode
    787878 787878 100% 0.19K 18759 42 150072K dentry

    free命令在find命令执行前后结果对比:
    [root@localhost ~]# free -m
                  total used free shared buff/cache available
    Mem: 1824 200 1534 15 89 1500
    Swap: 2047 196 1851
    [root@localhost ~]# free -m
                  total used free shared buff/cache available
    Mem: 1824 480 105 15 1238 1161
    Swap: 2047 196 1851

    vmstat在find命令执行前后对比:
    [root@localhost /]# vmstat 2
    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 201208 1570636 136 92168 0 0 5 5 16 19 27 3 70 0 0
     0 0 201208 1511788 136 149564 0 0 1702 0 491 599 2 6 90 1 0
     0 0 201208 1509428 136 149716 0 0 1106 0 478 801 0 2 98 0 0
    注:发表长度限制,省略部分测试显示


    作者回复: 原理分析加实践👍

    2019-01-21
    1
  • 划时代
    执行find / -name file-name,vmstat 1观察,in/cs/us/sy项参数有上涨,cache项有一点上涨,free项有一点下降,可想而知操作系统不会将所有目录项都存放在内存中,再执行tree /时尤为明显。
    回复老师问题,“内存打满”已处理属于某环境内存泄漏所致;Pss为0kB而Rss不为0kB,在Ubuntu中较少见,bash进程有出现一个,而在centos中则较多。
    2019-01-11
    1
  • Orcsir
    Flag。
    关于思考题:
    1.如果系统执行过一些操作,其中涉及到了要查找的file-name,那么在执行find命令的时候,应该是不会导致系统缓存的升高。
    2.如果不是上述情况,或者执行过命令 echo 3 > /proc/sys/vm/drop_cache 操作的话,那么是会导致系统缓存升高的。只是通过vmstat观察的话,buffer与cache都用相应的增加,但是buffer的增加更明显。至于原因的话,推测是这样的:buffer增加是因为系统会缓存读取到的块设备中的数据。cache增加是因为内核创建了目录项缓存用来保存inode节点的相关信息,而目录项缓存属于cache部分,所以会导致cache也增加。但是为什么buffer会比cache增加的明显,暂时还没想明白。
    2019-01-11
    1
  • ninuxer
    打卡day24
    阻塞非阻塞,同步异步再次mark下:
    根据应用程序是否阻塞自身线程的运行,可以把文件 I/O 分为阻塞 I/O 和非阻塞 I/O;
    根据是否等待响应结果,可以把文件 I/O 分为同步和异步 I/O
    2019-01-11
    1
  • Eilian
    倪老师,
          请教个问题,最近发现有台服务器会发生突然的cache 释放,系统会hang , 通过日志可以看到hang的时间段(通常为1分钟)会伴随这大量的cache 释放,其中 dentry cache 会由10G 释放后只有 几百兆,page cache 也是类似。但是系统free 的内存还有100G 左右(主机内存256G),不知道老师遇到过类似问题没有,或者这种问题应该从哪些方面去排查,求翻...
    2019-11-20
  • AB
    按我的理解,buffer和cache在buffer+cache中应该分别占用差不多50%,才能有一个很好的性能,可以这么理解么
    2019-09-24
  • AB
    老师,如果我看到buffer的值非常小,通过vmstat 1看到在100以内,是不是就能看出内存太小了,或者是应用程序占用了太多的内存,导致文件系统写磁盘没有通过buffer,而是直接裸IO的?
    2019-09-24
  • afterdream
    能不能形象化介绍一下通用文件模型中:超级块对象、索引节点对象、目录项对象、文件对象的作用?
    2019-08-07
  • kubxy
    老师,您好。我有一个疑问,内存中的目录项是如何生成的呢?
    我们都知道内存中的数据在关机后会丢失。目录项是由内核维护的,存储在内存中,那么关机时内存中的目录项如何处理:
    1)持久化到磁盘?下次开机直接从磁盘读入内存
    2)丢就丢呗(就这么任性),下次开机时由内核重新生成,如果是这种机制,那么问题又来了,如何生成呢,根据超级块和索引节点区计算吗?
    3)其他...

    作者回复: 从文件系统中恢复

    2019-05-25
收起评论
49
返回
顶部