什么是稀疏文件,我们为什么需要它?
What is a sparse file and why do we need it?
什么是稀疏文件,我们为什么需要它?
我唯一能得到的是它是一个非常大的文件,而且效率很高(以千兆字节为单位)。它的效率如何?
稀疏文件是一个大部分为空的文件,即它包含值为 0
(零)的大字节块。
在磁盘上,文件的内容存储在固定大小的块中(通常为 4 KiB 或更大)。当这样一个块中包含的所有字节都是 0
时,实现稀疏文件的文件系统不会将该块存储在磁盘上,而是将信息保存在文件元数据中的某处。
使用稀疏文件的优点:
- 空数据块不占用磁盘space;它们不存储为常规数据块,它们的标识符(仅使用几个字节)存储在文件元数据中;这样每个空块都会保存 4 KiB 的磁盘 space(或更多);
- 从稀疏文件中读取一个空数据块不需要时间;发生这种情况是因为没有从磁盘读取数据;因为文件系统知道块中的所有字节都是
0
,它只是将输入缓冲区中的所有字节设置为 0
,数据就绪;无需访问慢速存储设备;
- 将空数据块写入稀疏文件不需要时间;在写入时,文件系统检测到该块为空(其所有字节为
0
)并将块 ID 放入空块列表(在文件元数据中);没有数据写入磁盘。
有关稀疏文件的更多信息,请访问 Wikipedia page。
假设您有一个包含许多空字节的文件 \x00
。这些空字节 \x00
被称为空洞。存储空字节效率不高,我们知道文件中有很多空字节,为什么要将它们存储在存储设备上呢?我们可以改为存储描述这些零的元数据。当进程读取文件时,这些零字节块会动态生成,而不是存储在物理存储中(请查看维基百科的示意图):
这就是稀疏文件高效的原因,因为它不将零存储在磁盘上,而是保存足够的数据来描述将要生成的零。
注意:逻辑文件大小大于稀疏文件的物理文件大小。这是因为我们没有将零物理存储在存储设备上。
编辑:
当你 运行:
$ dd if=/dev/zero of=output bs=1G count=4
这里的命令将4G块的空字节复制到output
。要看到:
$ stat output
File: ouput
Size: 4294967296 Blocks: 8388616 IO Block: 4096 regular file
--omitted--
你可以看到这个文件有8388616块分配给它,这些块只存储从[=17复制的空字节 =] 并且它们确实占用物理磁盘 space,它们是存储在磁盘上的空洞(稀疏零)。 dd
完成了您的要求,将数据块从一个文件复制到另一个文件。
现在,运行 此命令检测漏洞并使文件就地稀疏:
$ fallocate -d output
$ stat output
File: swapfile
Size: 4294967296 Blocks: 0 IO Block: 4096 regular file
--omitted--
你注意到什么了吗?块数现在为 0,因为仅存储空字节的块已被取消分配。请记住,output
的块不存储任何内容,仅存储一堆空零,fallocate -d
检测到仅包含空零的块并释放它们,因为该文件的所有块都包含零,它们都是取消分配。
还要注意大小如何保持不变。这是文件的逻辑(虚拟)大小,而不是它在磁盘上的大小。重要的是要知道 output
现在不占用 物理 存储空间 space,它分配了 0 个块,因此我并没有真正使用磁盘 space。 运行ning fallocate -d
后保留的大小,因此当您稍后从文件中读取时,您会得到文件系统在 运行 时生成的空字节。然而,output
的物理大小为零,它不使用数据块。
请记住,当您读取 output
文件时,文件系统会在 运行 时动态生成空字节,它们 而不是 真正地物理存储在磁盘上,stat
报告的文件大小是逻辑大小,output
的物理大小为零。在这种情况下,文件系统必须在进程读取文件时生成 4G 的空字节。
要使用 dd
生成稀疏文件:
$ dd if=/dev/zero of=output2 bs=1G seek=0 count=0
$ stat
stat output2
File: output2
Size: 4294967296 Blocks: 0 IO Block: 4096 regular file
GNU dd
内部使用 lseek
和 ftruncate
,所以检查 t运行cate(2) 和 lseek(2)。
什么是稀疏文件,我们为什么需要它? 我唯一能得到的是它是一个非常大的文件,而且效率很高(以千兆字节为单位)。它的效率如何?
稀疏文件是一个大部分为空的文件,即它包含值为 0
(零)的大字节块。
在磁盘上,文件的内容存储在固定大小的块中(通常为 4 KiB 或更大)。当这样一个块中包含的所有字节都是 0
时,实现稀疏文件的文件系统不会将该块存储在磁盘上,而是将信息保存在文件元数据中的某处。
使用稀疏文件的优点:
- 空数据块不占用磁盘space;它们不存储为常规数据块,它们的标识符(仅使用几个字节)存储在文件元数据中;这样每个空块都会保存 4 KiB 的磁盘 space(或更多);
- 从稀疏文件中读取一个空数据块不需要时间;发生这种情况是因为没有从磁盘读取数据;因为文件系统知道块中的所有字节都是
0
,它只是将输入缓冲区中的所有字节设置为0
,数据就绪;无需访问慢速存储设备; - 将空数据块写入稀疏文件不需要时间;在写入时,文件系统检测到该块为空(其所有字节为
0
)并将块 ID 放入空块列表(在文件元数据中);没有数据写入磁盘。
有关稀疏文件的更多信息,请访问 Wikipedia page。
假设您有一个包含许多空字节的文件 \x00
。这些空字节 \x00
被称为空洞。存储空字节效率不高,我们知道文件中有很多空字节,为什么要将它们存储在存储设备上呢?我们可以改为存储描述这些零的元数据。当进程读取文件时,这些零字节块会动态生成,而不是存储在物理存储中(请查看维基百科的示意图):
这就是稀疏文件高效的原因,因为它不将零存储在磁盘上,而是保存足够的数据来描述将要生成的零。
注意:逻辑文件大小大于稀疏文件的物理文件大小。这是因为我们没有将零物理存储在存储设备上。
编辑:
当你 运行:
$ dd if=/dev/zero of=output bs=1G count=4
这里的命令将4G块的空字节复制到output
。要看到:
$ stat output
File: ouput
Size: 4294967296 Blocks: 8388616 IO Block: 4096 regular file
--omitted--
你可以看到这个文件有8388616块分配给它,这些块只存储从[=17复制的空字节 =] 并且它们确实占用物理磁盘 space,它们是存储在磁盘上的空洞(稀疏零)。 dd
完成了您的要求,将数据块从一个文件复制到另一个文件。
现在,运行 此命令检测漏洞并使文件就地稀疏:
$ fallocate -d output
$ stat output
File: swapfile
Size: 4294967296 Blocks: 0 IO Block: 4096 regular file
--omitted--
你注意到什么了吗?块数现在为 0,因为仅存储空字节的块已被取消分配。请记住,output
的块不存储任何内容,仅存储一堆空零,fallocate -d
检测到仅包含空零的块并释放它们,因为该文件的所有块都包含零,它们都是取消分配。
还要注意大小如何保持不变。这是文件的逻辑(虚拟)大小,而不是它在磁盘上的大小。重要的是要知道 output
现在不占用 物理 存储空间 space,它分配了 0 个块,因此我并没有真正使用磁盘 space。 运行ning fallocate -d
后保留的大小,因此当您稍后从文件中读取时,您会得到文件系统在 运行 时生成的空字节。然而,output
的物理大小为零,它不使用数据块。
请记住,当您读取 output
文件时,文件系统会在 运行 时动态生成空字节,它们 而不是 真正地物理存储在磁盘上,stat
报告的文件大小是逻辑大小,output
的物理大小为零。在这种情况下,文件系统必须在进程读取文件时生成 4G 的空字节。
要使用 dd
生成稀疏文件:
$ dd if=/dev/zero of=output2 bs=1G seek=0 count=0
$ stat
stat output2
File: output2
Size: 4294967296 Blocks: 0 IO Block: 4096 regular file
GNU dd
内部使用 lseek
和 ftruncate
,所以检查 t运行cate(2) 和 lseek(2)。