Linux磁盘专题-linux文件系统详解

这可是我几年前的杰作笔记呀.....当初手写计算都会,现在忘光光....

物理硬盘Block的概念和作用

硬盘底层一次IO就是读、写一次扇区,一个扇区默认是512Byte。
读写大量文件如果以扇区为单位会很慢、性能不好,  
  所以出现了逻辑块的概念(logic block),也就是硬盘Block。
  逻辑块Block是由硬盘驱动器所维护和操作的,它并非和扇区一样物理划分,因此一个硬盘逻辑块Block可能包含不止一个扇区。
  每个硬盘Block都由一个LAB(logic Block address)。
  硬盘控制对数据的操作就是以硬盘逻辑块Block为单位,并且能识别计算出对应的扇区并进行读取和写入。
  

文件系统Block的概念和作用

文件系统中也提供了一个叫Block的概念,文件系统的Block一般为1024Byte(1KB)、2048Byte(2KB)、4096Byte(4KB)。
文件系统Block是由文件系统去维护和操作的,它知道如何将文件系统Block转换并计算出为对应的硬盘Block的LBA地址。

另外注意的是:
  1、当一个文件小于1024byte时,那么它也要占用一个文件系统Block,如果文件系统Block默认时4096byte的情况下,更加浪费空间。
    所以,如果分区的时候,如果确定以后大部分都是小文件的情况下,可以将文件系统的Block设置成小一些,可以提高性能。相反,如果文件系统中大部分都是体积较大的文件,可以将文件系统Block设置成大一些,以提升性能。

文件读取写入的大概过程

比如读取一个文件系统Block。
  先通过文件系统计算出文件系统Block对应的硬盘Block(也就是计算出LBA),然后通知硬盘驱动器通过LBA去读取扇区数据。

inode的作用和出现的原因

想象以下,假设现在划分了一个分区(分区就是创建文件系统)并将其文件系统Block设置为1024byte(1KB)。
  分区里面有一个10MB的文件,那么它就要占用10240个Block,(1MB=1024KB,1KB=1024B,一个Block等于1KB,所以换算后是10240KB)
    而且10240个Block可能并不是顺序存放。
    假设我们要读取这个文件,如果要从前往后扫描整个文件系统的话会非常慢、性能差。
    
    这时候inode(index node,i节点)的出现将很好的解决上面提到的性能问题。
    通过在inode中标注下文件元数据,如:文件所占用的所有Block的位置、文件权限、文件类型、文件属主、大小等等信息。
    通过读取inode中文件占用的文件系统Block的地址,来读取文件数据。
    
    并且由于inode的体积小,一般一个inode的默认大小是256byte(新),以前是128Byte。相对扫描整个文件系统,扫描inode速度更新,性能更好。
    但是和文件系统Block一样,文件大小也可能小于inode的大小,比如一个文件的体积只有1byte。
    
    所以在创建文件系统时,可以手动设置inode的大小。(但是好像大部分时候都没有去特意设置)
      小文件较多的分区,可以将inode的默认体积设置为小一些,相反大文件较大的分区可以设置大一些。
        (inode的大小,最小只能是128Byte,设置的时候只能是2的幂次方。ext4默认是256Byte)
    另外创建文件系统时,可以设置每多少个Block就分配一个inode,
      小文件较多的分区,可以将其设置为小一些(但不能小于Block大小,因为会造成inode过多,造成多余);相反大文件较多的分区可以设置大一些,以较少iNode数量,提升inode Table扫描速度。
      
  【总结】:
  inode的出现就是提升读取block时候的性能。使用inode存储文件的各种元数据,通过读取inode中引用的block地址来读取文件。而不需要扫描整个文件系统block。
  注意:iNode也会占据一个文件系统block,因为inode默认大小是128byte或者256byte。
    而文件系统默认每个block大小是1024byte、2048byte、4096byte、等等。
    
    因此有引出了一个问题:
      一个inode难道就让他占用一个文件系统block吗?这样未必也太浪费空间了。
      所以就出现了inode table(将所有inode集中起来,以表的形式存放)。
      inode table后面再说。

block bitmap的出现和作用

想象一下,文件系统有很多个Block,此时当我们写入一个文件时,我们需要扫描整个文件系统block,然后再来分析出每个Block是否被使用?这样效率会不会很低?文件系统体积小的时候还好,如果是1T 、10T呢?

此时,将每个block使用0和1二进制位来表示是否被使用,1Byte=8bit,一个byte就可以标识8个block。
  相对于扫描整个文件系统Block,扫描block bitmap效率更高!
  
  【例子1】:
  比如一个1GB的文件系统,假设文件系统默认一个Block大小为:4096byte(4KB),则文件系统一共有:
    1KB=1024B;1MB=1024KB;1GB=1024MB
    
    (1024MB*1024KB=1048576KB)
    (1048576KB)/4KB=262144个Block,文件系统共有262144个block。
    
    1Byte=8bit,一个byte就可以标识8个block。
    block bitmap所需要使用的总共体积是:262144/8=32768Byte/1024=32KB
      也就是说只需要扫描这32KB就可以知道这1GB的block是否空闲,速度提升很大。
    
  【例子2】:
    假设文件系统默认Block大小为:1024Byte (1KB),则1G的文件系统一共有:
    1024*1024=1048576个Block (1024MB*1024KB=1048576KB)
    block bitmap所需要使用的总共体积是:1048576/8=131073byte=128KB
      也就是说只需要扫描128KB就可以回到这1GB的分区的所有文件系统block是否空闲。
  
  总结:通过上面两个例子可以得出结论,扫描block bitmap的体积相对扫描整个文件系统block体积要快得多,可以更快的知道文件系统上所有的block哪个可以使用(写入数据),哪个已经被使用。

inode table的出现和作用

上面说的inode时已经引出了该问题:
  一个inode难道就让他占用一个文件系统block吗?这样未必也太浪费空间了。
  所以就出现了inode table(将所有inode集中起来,以表的形式存放)。

将所有inode集中起来存放,假设有一个文件系统,文件系统的默认每个block是1024byte,每个inode默认是128byte。那么一个文件系统block可以存放1024/128=8个inode。这样能充分使用一个文件系统block,而不造成浪费。

思考:
  虽然inode table的出现已经能够充分利用文件系统block而不造成浪费,但是如果文件系统很大,分配的inode正常来讲也会变得更多,inode多的话,那么inode table的体积也会大,那么在扫描inode table时也会影响性能。
  
  那么该如何优化?
    答:通过对文件系统block进行以组为单位的划分,每个组里面存放自己的inode 、inode table、block bitmap等信息。这就是block group。在说block group前,我们先说一下inode bitmap。
    

inode bitmap的出现和作用

前面说过,inode是记录文件的元数据的,其中包含引用文件系统block的地址。
  而inode table是将所有inode集中起来,减少文件系统block的浪费以及方便文件系统集中管理。
  
那么不管我们是读取还是写入文件都需要经过扫描整个inode table中的所有inode看看是否被使用?这样效率会不会很低?道理和block bitmap出现和作用是一样的,如果需要扫描整个inode table效率很低,
  此时使用0和1二进制为来表示inode是否可以被使用,能够大幅度提升性能。
    

block group的出现和作用

前面说的block bitmap、inode table、inode bitmap虽然都有优化性能,但当文件系统很大时候,上述的block bitmap、inode table、inode bitmap 体积也会很大。
此时,我们可以对文件系统的所有block进行逻辑性的划分(也就是说block group也是文件系统的一个逻辑性的概念),这便是称为block group(块组)。
  每个文件系统(分区)包含多个block group,每个block group中包含元数据和data block,元数据则是存放上面提到的block bitmap、indeo table 、inode bitmap等。
  
  PS:再提一下:按照磁盘的物理性来将,划分分区都是按柱面进行划分(划分成多个文件系统,创建多个不同的、或者相同的文件系统)

block group块组的编号是从0开始的。

block group 的划分

block group在创建文件系统的时候就已经默认划分完了,如果需要修改,只能在创建文件系统的时候进行指定。

一个分区有多少个block group是如何确定的呢?
  答:先根据文件系统设定每个block的默认大小(比如4096Byte、1024Byte),
    然后根据一个block bitmap里面可以记录多少block是否空闲就可以确认要划分多少个block group.

假设一个1GB的分区,默认block设置是1024Byte,
每个block大小假设是1KB,1024byte * 8 bit = 8192个block ,1KB就可以记录8192个block。

也就是一个bitmap占用一个block,那么一个bitmap可以记录8192个block是否空闲。

  上面提到一个Block是1KB,8192个block就是8192KB=8MB。
  
  创建一个1GB的分区需要划分1024MB/8MB=128个block group。


假设一个512M的分区,文件系统每个block默认是4096byte 。
  那么该分区总共有多少个block:
    512MB*1024KB=524288KB/4KB=131072个block
    
  一个bitmap占用一个block,4096byte*8bit=32768个block,一个bitmap就可以记录32768个block是否被使用。  一个block是4KB,32768个block就是32768KB*4KB=131072KB=128MB。
  创建一个512M的分区,block默认是4KB的情况下,需要划分512/128=4个block group。

[root@vm-centos7 ~]# mkfs.ext4 /dev/sdb1
mke2fs 1.42.9 (28-Dec-2013)
文件系统标签=
OS type: Linux
块大小=4096 (log=2)
分块大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
32768 inodes, 131072 blocks   ### 总共有131072个block
6553 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=134217728
4 block groups  ### 划分了4个block group
32768 blocks per group, 32768 fragments per group    ### 每个block group里面有32768个block
8192 inodes per group   ### 每个block group中inode的数量
Superblock backups stored on blocks:
        32768, 98304

Allocating group tables: 完成
正在写入inode表: 完成
Creating journal (4096 blocks): 完成
Writing superblocks and filesystem accounting information: 完成
    

superblock超级块的出现和作用

superblock是用来记录文件系统(分区)中到底有多少个block group(块组),以及每个block group中的元属性,如:inode总数、block总数、空闲的block数量、空闲的inode数量等等。


[root@vm-centos7 ~]# dumpe2fs /dev/sdc1 -h
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          67fab7af-55b9-4bed-9d13-5158d81f303e
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              1048576
Reserved block count:     52428
Free blocks:              996238
Free inodes:              65525
First block:              1
Block size:               1024
Fragment size:            1024
Group descriptor size:    64
Reserved GDT blocks:      256
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         512
Inode blocks per group:   128
Flex block group size:    16
Filesystem created:       Wed Jun 29 14:07:04 2022
Last mount time:          n/a
Last write time:          Wed Jun 29 14:07:04 2022
Mount count:              0
Maximum mount count:      -1
Last checked:             Wed Jun 29 14:07:04 2022
Check interval:           0 (<none>)
Lifetime writes:          32 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      3f713e4f-b1a5-49ad-9f6d-1a267ce04fc7
Journal backup:           inode blocks
Journal features:         (none)
日志大小:             32M
Journal length:           32768
Journal sequence:         0x00000001
Journal start:            0

例子:

mkfs-创建文件系统(格式化分区)

假设:
    文件系统为1GB。
    block size=4096byte。(4KB)
    inode size=256byte。(mkfs默认设置,也可以手动设置)
    默认每16KB分配一个inode。[(mkfs默认设置,也可以手动设置))](https://www.wolai.com/c9T2EJo4rQHSj2hf3ud56w)

多少个block分配一个inode?
  答:一个block为4KB,每16个block分配一个inode,16/4=4,也就是4个block就分配一个inode、

改分区总共有多少个block?
  答:假设1GB文件,那么总共有1024MB*1024KB=1048576KB/4=262144个block。
  
分区的总inode数是多少?
  答:block数量/每多少个block分配一个inode,即:262144/4=65536个inode。

有多少个block group?
答:
  每一个block group中的block bitmap占用了一个block。
  一个block bitmap占用一个block,一个block bitmap可以记录 4096byte*8bit=32768的block是否被占用。
  一个block是4KB,那么一个block group中最多总共有:32768个block,
    而一个block是4KB,那么一个block group体积最大就是: 32768KB*4KB=131072KB=128MB。
  
  文件系统是1GB=1024MB,即1024/128=8个block group。
  
每个block group的inode数是多少?
  答:总inode数/block group数   即:65536/8=8192个inode。

block group中的inode table占用多少个block?
答:一个inode默认占用体积是256byte,
  一个block group的inode table则占用:每个inode大小 * 每个block group的inode数 
    即:256*8192=2097152byte=2048KB ,而一个block默认是4KB,则inode table占用了: 2048/4=512个block。
posted @ 2023-07-17 15:12  蕝戀  阅读(112)  评论(0编辑  收藏  举报