- 你 ls -lh ./test.txt 命令看会发现是一个 100 G 的文件;
- 但是 du -sh ./test.txt 会发现是一个 0 字节的文件;
- stat ./test.txt 会发现是 Size: 107374182400 Blocks: 0 的文件;
下面这种 1T 的文件,因为只写了头尾 8K 数据,所以只需要分配 2 个 block 存储用户数据即可 。

文章插图
好,我们再深入思考下,文件系统为什么能做到这个?
这也是为什么理解稀疏语义要先了解文件系统的实现的原因 。
- 首先,最关键的是把磁盘空间切成离散的、定长的 block 来管理;
- 然后,通过 inode 能查找到所有离散的数据(保存了所有的索引);
- 最后,实现索引块和数据块空间的后分配;
稀疏语义接口
为了知识的完整性,简要介绍稀疏语义的几个接口:
- preallocate(预分配):提供接口可以让用户预占用文件内指定范围的物理空间;
- punch hole(打洞):提供接口可以让用户释放文件内指定范围的物理空间;
预分配的意思是?
就是说,当你创建一个 1T的文件,如果你没写数据,这个时候其实没有分配物理空间的,支持稀疏语义的文件系统会提供一个 fallocate 接口给你,让你实现预分配,也就是说把这 1T 的物理空间现在就分配出来 。
思考:这个有什么好处呢?
- 第一,如果你命中注定要 1T 的空间,预分配是有好处的,把空间分配的工作量集中在初始化的时候一把做了,避免了实时现场分配的开销;
- 第二,如果不提前占坑,很有可能等你想要的时候已经没有空间可占用了 。所以你把物理空间先占好,就可以安心使用了;
fallocate -o 0 -l 4096 ./test.txt这个命令的意思就是给 text.txt 这个文件 [0, 4K] 的位置分配好物理空间 。打洞(punch hole) 是干啥的呢?
这个调用允许你把已经占用的物理空间释放掉,从而达到快速释放的目的 。这种操作在虚拟机镜像的场景用得多,通常用于快速释放空间,punch hole 能够让业务更有效的利用空间 。
linux 提供了一个 fallocate 命令也可以用来 punch hole 空间 。
fallocate -p -o 0 -l 4096 ./test.txt这个命令的意思是把 test.txt [ 0, 4K ] 的物理空间释放掉 。Go 语言实现
稀疏文件本身和编程语言无具体关系,可以用任何语言实现,我下面以 Go 为例,看下稀疏文件的预分配和打洞(punch hole)是怎么实现的 。
预分配实现:
func PreAllocate(f *os.File, sizeInBytes int) error { // use mode = 1 to keep size // see FALLOC_FL_KEEP_SIZE return syscall.Fallocate(int(f.Fd()), 0x0, 0, int64(sizeInBytes))}punch hole 实现:// mode 0 change to size 0x0// FALLOC_FL_KEEP_SIZE = 0x1// FALLOC_FL_PUNCH_HOLE = 0x2func PunchHole(file *os.File, offset int64, size int64) error { err := syscall.Fallocate(int(file.Fd()), 0x1|0x2, offset, size) if err == syscall.ENOSYS || err == syscall.EOPNOTSUPP { return syscall.EPERM } return err}可以看到,本质上都是系统调用 fallocate ,然后带不同的参数而已 。指定文件偏移和长度,就能预分配物理空间或者释放物理空间了 。这里有一个知识点:punch hole 的调用要保证 4k 对齐才能释放空间 。
举个例子,比如:
punch hole [0, 6k] 的数据,你会发现只有 [0, 4k] 的数据物理块被释放了,[4k, 6k] 所占的 4k 物理块还占着空间呢 。
推荐阅读
- Linux查看硬件信息超强命令sar,以及可视化工具ksar
- 微信正在用的深度学习框架开源!支持稀疏张量,基于C++开发
- PC电脑|5分钟开机上千台 无影云电脑免费体验1周:Win、Linux通吃
- linux内核SMP负载均衡浅析
- 浅谈在Linux中如何将脚本做成系统服务开机自启动
- 寒湿型肥胖喝什么茶,喝什么茶排寒湿深度好文
- Linux服务器磁盘满了怎么办
- 色相饱和度深度解析,photoshop明度观察层是什么?原理讲解
- linux安装php步骤详解
- 「linux专栏」top命令用法详解,再也不怕看不懂top了
