会挽雕弓如满月,西北望,射天狼。|

园龄:粉丝:关注:

文件系统:ext4 的 block 分布(1G分区为例)

在逻辑上,我们可以把硬盘空间想象成一个一维的整数数列,在这个数列上每个数字都代表一个4K大小的块。一个1G的硬盘分区,其块数是262144。

>>> 262144 * 4 / 1024 / 1024
1.0

我们可以想象一辆超级磁悬浮列车上有264144节车厢,编号从1开始递增。每个车厢都有门可以进出乘客,也有窗户可以看到里面乘客的情况。这辆列车只有一个操作员,把他想象成一个指向车厢的指针。乘客需要经过这个指针进入车厢,想要了解车厢里面的情况,也需要通过这个指针。我们再假设这个指针滑动的速度接近光速,而送乘客上车厢和了解一个车厢的信息都需要一个滴答。在只追求存储效率的情况,指针只需要让乘客按顺序去坐满所有车厢就行,而不用做任何记录,总共需要264144个滴答;但是在这种情况下,读出任何一个车厢的信息所需要的平均时间是(264144/2)个滴答,读出任意两个车厢信息的平均时间是(264144/2)+(264144/2)个滴答,依此递增。但是我们写数据的目的是为了读出,为了平衡读与写的效率,于是有了文件系统。

当硬盘分区被格式化成ext4文件系统时,这个整数数列的磁悬浮列车又会发生什么变化呢?

计算开始

总的block数量:262144

$ dumpe2fs /dev/vg01/test  | grep "Block count"
dumpe2fs 1.42.9 (28-Dec-2013)
Block count:              262144

数据块数量: 249830

$ df -B 4k /mnt
Filesystem            4K-blocks  Used Available Use% Mounted on
/dev/mapper/vg01-test    249830   641    231986   1% /mnt

>>> 262144 - 249830
12314

>>> 249830/262144
0.9530258178710938

# 可以看到,格式化后硬盘的存储空间利用率为95.3%

inode块数量:4096

$ dumpe2fs /dev/vg01/test  | grep "Inode count"
dumpe2fs 1.42.9 (28-Dec-2013)
Inode count:              65536

$ dumpe2fs /dev/vg01/test  | grep "Inode size"
dumpe2fs 1.42.9 (28-Dec-2013)
Inode size:               256

inode块数:(65536*256)/(4*1024)
>>> (65536*256)/(4*1024)
4096.0
>>> 12314 - 4096
8218

>>> 4096/262144
0.015625

# inode的占比为1.56%

位图块数量:16

# 每个块组1个inode位图+1个数据块位图,8个块组,使用16个块
$ dumpe2fs /dev/vg01/test  | grep "Group" | grep Blocks
dumpe2fs 1.42.9 (28-Dec-2013)
Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED]
Group 2: (Blocks 65536-98303) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Group 3: (Blocks 98304-131071) [INODE_UNINIT, ITABLE_ZEROED]
Group 4: (Blocks 131072-163839) [INODE_UNINIT, ITABLE_ZEROED]
Group 5: (Blocks 163840-196607) [INODE_UNINIT, ITABLE_ZEROED]
Group 6: (Blocks 196608-229375) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Group 7: (Blocks 229376-262143) [INODE_UNINIT, ITABLE_ZEROED]

>>> 8218 - 16
8202

# 为什么是8个块组?看下面这个算式:
>>> 262144 / (4*1024*8)
8.0

# 位图?顾名思义,每个bit位标识一个块有无使用。

5个superblock + 5个 Group descriptors

$ dumpe2fs /dev/vg01/test  | grep "superblock"
dumpe2fs 1.42.9 (28-Dec-2013)                                                                                                             
  Primary superblock at 0, Group descriptors at 1-1
  Backup superblock at 32768, Group descriptors at 32769-32769
  Backup superblock at 98304, Group descriptors at 98305-98305
  Backup superblock at 163840, Group descriptors at 163841-163841
  Backup superblock at 229376, Group descriptors at 229377-229377

>>> 8202 - 10
8192

ext4的日志系统使用块数:8192

$ dumpe2fs /dev/vg01/test  | grep Journal 
dumpe2fs 1.42.9 (28-Dec-2013)
Journal inode:            8
Journal backup:           inode blocks
Journal features:         journal_64bit
Journal size:             32M
Journal length:           8192
Journal sequence:         0x00000002
Journal start:            1

>>> 8192/262144
0.03125

# ext4日志系统占比3.1%

计算完毕。空间利用效率约为95.3%。

实际中,数据块也会用于记录数据块的编号信息,使空间利用率下降,但不多;而日志系统的占比随者硬盘分区变大而变小,这又会提高硬盘的空间利用率。

读出的时间效率

/1.txt为例,为了读出该文件,操作系统首先需要知道/的inode地址,我们假设这个信息已经被加载到内存。inode中有数据块的编号信息,通过该编号可以到数据块中读取信息。

第一个滴答用于读取/的数据块,其中包含了目录下所有文件以及目录的inode地址,以此获得 1.txt 的 inode 地址;

第二个滴答用于读取1.txt的inode块,获得存储文件的数据块编号

第三个滴答用于读取1.txt的数据块信息

实际上,第一个滴答的信息很可能就已经在内存中了,第二个也可能,第三个也可能。

按照上面的方法,如果是要读出/a/1.txt呢?只需要增加两个滴答分别去读取目录ainode信息数据块信息

上面的计算隐含了这样一个假设:即1.txt文件只需要1个数据块进行存储。实际中,文件的存储可能需要多个数据块,那么每多一个数据库块就需要增加一个滴答。此外,一个inode可以直接记录的数据块编号数量是12,超出部分需要额外的数据块来存储。在inode中,除了有12个可以直接指向数据块的记录,还有1个单间接存储块记录、1个双间接存储块记录、1个三间接存储块记录。假设一个数据块编号的记录是4B,一个单间接块可以存1024个数据块编号,即支持文件最大为4M;那么双间接块为4G,三间接块为4T。总之,文件的读取时间随文件大小而增加,但是会很合理。

附录

superblock

超级块是文件系统中的关键元数据结构,它记录了整个文件系统的属性和配置信息。超级块存储在文件系统的固定位置,通常是文件系统的第一个块,用于描述文件系统的整体信息,包括文件系统的大小、块大小、inode表位置、块组描述符表位置等。超级块的备份通常也存储在其他位置,以便于文件系统的恢复。

Group descriptors

Group descriptors(块组描述符)是ext2/ext3/ext4文件系统中的另一个重要结构,用于描述文件系统的块组(block group)。文件系统将整个存储空间划分为若干个块组,每个块组包含一组连续的数据块,以及与之相关的元数据结构。块组描述符表存储了每个块组的元数据信息,例如块位图的位置、inode位图的位置、inode表的起始位置等。块组描述符表通常存储在文件系统的固定位置,紧随超级块之后。(块组的数量 / 64 + 1,得到块组描述符需要的数据块数。)

dumpe2fs

打印出 superblock 和 Group descriptors 记录的全部信息。

inode相关

  1. 每当创建一个目录或者文件时都会分配一个inode,用于记录文件或目录的元数据信息,比如文件大小、创建时间、修改时间、访问时间等。此外,它还包含了指向存储文件数据块位置的指针。
  2. inode的大小为一般为256byte,也可能是128byte,所以一个4K块中会有16个inode或者32个inode。

本文作者:武平宁

本文链接:https://www.cnblogs.com/dewan/p/what_the_mkfs_disk_do.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   武平宁  阅读(310)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起