linux文件系统由什么组成(linux文件系统格式查看)
linux文件系统工作原理
索引节点和目录项
linux是所有文件,普通文件、目录、块设备、套接字和管道也要通过统一的文件系统进行管理。Linux为每个文件分配了两种数据结构,索引节点和目录项,主要用来记录文件的元信息和目录结构。
节点:inode,用于记录文件的元数据,如inode编号、文件大小、访问权限、修改日期、数据位置等。索引节点与文件一一对应。目录:dentry,记录文件名、索引节点指针和其他目录项的关系。与索引节点不同,目录项是由内核维护的内存数据结构,也称为目录项缓存。索引节点是每个文件的唯一符号,目录项维护文件系统的树结构。目录项和索引节点之间是多对一的关系,可以简单理解为:一个文件可以有多个别名。
通过硬链接为文件创建的别名将对应于不同的目录项,这些目录项本质上链接到同一个文件,因此它们的索引节点是相同的。
磁盘的最小单位是扇区(512B),但每次读写效率都很低。因此,在文件系统中,连续的扇区由逻辑块组成,并且每次逻辑块被用作管理数据的最小单元,并且每次逻辑块被用作管理数据的最小单元。公共逻辑块的大小为4KB,由八个连续的扇区组成。
注意两点:
目录本身是一个内存缓存,索引节点是存储在磁盘中的数据。为了协调cpu和磁盘之间的速度差异,文件内容将缓存在页面缓存中。自然,这些索引节点也将缓存在内存中。当执行文件系统格式时,用于加速文件访问的磁盘将被分成三个存储区域,即超级块、索引节点区域和数据块区域。超级块:存储整个文件系统的状态;索引节点区:存储索引节点;数据块区:存储文件数据。
虚拟文件系统
目录项、索引节点、逻辑块和超级块构成了linux文件系统的四个元素。为了支持各种文件系统,linux在用户进程和文件系统之间引入了一个抽象层,即虚拟文件系统VFS。VFS定义了一组所有文件系统都支持的数据结构和标准接口。
00-1010 I/O分类:缓冲和非缓冲I/O、直接和间接I/O、阻塞和非阻塞I/O、同步和异步I/O
缓冲区I/O是指利用标准库缓存加快文件的访问速度,然后通过标准库内部的系统调度来访问文件;无缓冲输入/输出:通过系统调用直接访问文件,而不是标准的库缓存。“缓冲区”是指在标准库中实现的缓存。例如,您可能已经看到,许多程序只有在遇到换行符时才会输出,换行符之前的内容实际上是由标准库临时缓存的。直接I/O:跳过操作系统的页面缓存,直接与文件系统交互访问文件;非直接输入输出正好相反。读写文件时,必须先经过系统的页面缓存,然后由内核或附加系统调用,实际写入磁盘。如果是在数据库等场景中,还会看到跳过文件系统读写磁盘的情况,也就是我们通常所说的裸I/O阻塞I/O,非阻塞I/O同步I/O异步I/O空间不足,df看磁盘发现还有很多剩余空间。
事实上,除了文件数据,索引节点也占用磁盘空间。使用以下命令:
df -i
当发现索引节点不足,磁盘空间充足时,可能是小文件太多造成的。这个问题可以通过删除这些小文件或将它们移动到具有足够索引节点的其他磁盘上来解决。
使用内核Slab机制来管理目录条目和索引节点的缓存。/proc/meminfo仅给出了Slab的整体大小,该大小特定于每个Slab缓存。也请检查/proc/slabinfo。
存储系统输入输出的工作原理:
文件系统层,包括vfs等文件系统的具体实现;为应用程序提供标准的文件访问接口;下层通过通用块层存储和管理磁盘数据;通用块层:包括块设备I/O队列和I/O调度器。文件系统的I/O请求将被排队,然后通过重新排序和请求合并发送到下一个设备层。设备层,包括存储设备和相应的驱动程序,负责最终物理设备的I/O和存储系统的I/O,通常是整个系统中最慢的环节。因此,Linux通过各种缓存机制优化了I/O效率。例如,为了优化文件访问的性能,将使用各种缓冲机制,如页面缓存、信息节点缓存和目录项缓存,以减少对底层数据块设备的直接调用。同样,为了优化块设备的访问效率,使用缓冲器来缓存块设备的数据。
00-1010利用率指磁盘处理I/O的时间百分比,利用率过高意味着磁盘I/O存在性能瓶颈;饱和、磁盘处理I/O的繁忙程度、过度饱和意味着磁盘存在严重的性能瓶颈。IOPS:每秒I/O请求吞吐量:每秒I/O请求大小响应时间:指发送I/O请求和接收响应之间的时间间隔。利用率只考虑是否有I/O,不考虑I/O的大小,换句话说,当利用率为100%时,磁盘仍可能接受新的I/O请求。
我们不能孤立地比较一个指标,而是结合读写比、I/O的类型(随机或连续)、I/O的大小来综合分析;在数据库、大量随机读写的小文件等场景中,IOPS可以更好地反映系统的整体性能。然而,在多媒体等读写顺序较多的场景中,吞吐量可以更好地反映系统的整体性能。
遇到这种“疯狂伐木”的场景,可以使用iostat和strac。
e、lsof等工具来定位狂打日志的进程,找出相应的日志文件,再通过应用程序的接口,调整日志级别来解决问题。如果应用程序不能动态调整日志级别,你可能还需要修改应用的配置,并重启应用让配置生效。首页用top、iostat,分析了系统的 CPU和磁盘使用情况。我们发现了磁盘I/O瓶颈,也知道了这个瓶颈是案例应用导致的。接着我们试着照搬上一节案例的方法,用strace来观察进程的系统调用,不过这次很不 走运,没找到任何 write 系统调用。于是,我们又用了新的工具,借助动态追踪工具包 bcc 中的 filetop 和 opensnoop ,找 出了案例应用的问题,发现这个根源是大量读写临时文件。找出问题后,优化方法就相对比较简单了。如果内存充足时,最简单的方法,就是把数据 都放在速度更快的内存中,这样就没有磁盘I/O的瓶颈了。当然,再进一步,你可以还可以利用Trie树等各种算法,进一步优化单词处理的效率为什么strace跟踪这个进程,却没有发现任何 write 系统调 用?
因为写文件是由子线程执行的,所有strace跟踪进程没有看到write系统调用,可以通过pstree查看进程的线程信息,再用strace跟踪;或者通过strace -fp pid跟踪所有线程
慢查询分析
top、iostat 分析了系统的 CPU 和磁盘使用情况,发现了磁盘的 I/O 瓶颈。接着,我们借助 pidstat ,发现瓶颈是 mysqld 导致的。紧接着,我们又通过 strace、 lsof,找出了 mysqld 正在读的文件。同时,根据文件的名字和路径,我们找出了mysqld 正在操作的数据库和数据表。综合这些信息,我们判断,这是一个没有利用索引导致的慢查询问题。
停止dataservice后,IO问题也会消失,为什么?
案例应用访问的数据表,基于 MyISAM 引擎,而 MyISAM 的一个特点,就是只在内存中缓存索引,并不缓存数据。所以,在查询语句无法使用索引时,就需要数据表从数据库文件读入内存,然后再进行处理。
dataservice 会不停的释放文件缓存,导致mysql不会利用磁盘缓存。
redis慢
先用top、iostat分析了系统的CPU、内存和磁盘使用情况,不过却发现,系统资 源并没有出现瓶颈。为了进一步分析,就需要你对系统和应用程序的工作原理有一定的了解。 比如,今天的案例中,虽然磁盘 I/O并没有出现瓶颈,但从 Redis的原理来说,查询缓存 时不应该出现大量的磁盘I/O写操作。顺着这个思路,我们继续借助 pidstat、strace、lsof、nsenter等一系列的工具,找出了两个潜在问题,一个是Redis的不合理配置,另一个是 Python 应用对Redis的滥用I/O基准测试工具
fio(flexible I/O Tester)
I/O性能优化
应用的优化
用追加写代替随机写,减少寻址开销,加快 I/O 写的速度借助缓存 I/O ,充分利用系统缓存,降低实际 I/O 的次数应用程序内部构建自己的缓存,或者用 Redis 这类外部缓存系统。这样,一 方面,能在应用程序内部,控制缓存的数据和生命周期;另一方面,也能降低其他应用程序使用缓存对自身的影响。C 标准库提供的 fopen、fread等库函数,都会利用标准库的缓存,减少磁盘的操作。而你直接使用open、read等系统调用时,就只能利用操作系统提供的页缓存和缓冲区等,而没有库函数的缓存可用需要频繁读写同一块磁盘空间时,可以用 mmap 代替 read/write,减少内存的 拷贝次数在需要同步写的场景中,尽量将写请求合并,而不是让每个请求都同步写入磁盘, 即可以用 fsync() 取代 O_SYNC在多个应用程序共享相同磁盘时,为了保证 I/O 不被某个应用完全占用,推荐你使 用 cgroups 的 I/O 子系统,来限制进程 / 进程组的 IOPS 以及吞吐量在使用CFQ调度器时,可以用 ionice来调整进程的I/O调度优先级,特别是提高核心应用的I/O优先级。ionice支持三个优先级类:Idle、Best-effort和Realtime。其中,Best-effort 和 Realtime还分别支持0-7的级别,数值越小,则表示优先级别越高。