什么是稀疏文件,我们为什么需要它?

Posted

技术标签:

【中文标题】什么是稀疏文件,我们为什么需要它?【英文标题】:What is a sparse file and why do we need it? 【发布时间】:2017-08-24 21:41:24 【问题描述】:

我唯一能得到的是它是一个非常大的文件并且它很高效(以千兆字节为单位)。效率如何?

【问题讨论】:

据我了解背后的技术是,如果你有很多 0 字节块的大文件(例如,你正在使用哈希算法计算存储数据的位置),操作系统不会分配 0 字节的块,只分配你需要的数据。我以前从未使用过它,因为我从未有过我描述的任务。 0 字节的块?请解释@nabuchodonossor 好的,你也可以谷歌(微软 ntfs 稀疏文件)并从那里找到解释,但你问了,所以我复制并粘贴了一点:“其中大部分数据为零的文件据说包含稀疏数据集。像这样的文件通常非常大,例如,包含要处理的图像数据的文件或高速数据库中的矩阵。包含稀疏数据集的文件的问题是大部分文件不包含有用的数据,因此,它们对磁盘空间的使用效率低下......" 【参考方案1】:

假设您有一个包含许多空字节\x00 的文件。这些许多空字节\x00 被称为空洞。存储空字节效率不高,我们知道文件中有很多空字节,那么为什么要将它们存储在存储设备上呢?我们可以改为存储描述这些零的元数据。当一个进程读取文件时,这些零字节块会动态生成,而不是存储在物理存储中(查看 Wikipedia 中的此示意图):

这就是稀疏文件高效的原因,因为它不会将零存储在磁盘上,而是保存足够的数据来描述将生成的零。

注意:逻辑文件大小大于稀疏文件的物理文件大小。这是因为我们没有将零物理存储在存储设备上。


编辑:

当你运行时:

$ 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块分配给它,这些块只存储从/dev/zero复制的空字节,它们确实占用了物理磁盘空间,它们是存储在磁盘上的孔(稀疏零)。 dd 完成了您的要求,将数据块从一个文件复制到另一个文件。

现在,运行这个命令来检测漏洞并使文件就地稀疏:

$ fallocate -d output
$ stat output
File: swapfile
  Size: 4294967296      Blocks: 0          IO Block: 4096   regular file
--omitted--

你注意到什么了吗?现在的块数为 0,因为仅存储空字节的块已被释放。请记住,output 的块不存储任何内容,只有一堆空零,fallocate -d 检测到仅包含空零的块并释放它们,因为该文件的所有块都包含零,所以它们都被释放。

还要注意大小是如何保持不变的。这是文件的逻辑(虚拟)大小,而不是它在磁盘上的大小。知道output 现在不占用物理 存储空间至关重要,它分配了0 个块,因此我并没有真正使用磁盘空间。运行fallocate -d 后保留的大小,因此当您稍后从文件中读取时,您会得到文件系统在运行时为您生成的空字节。然而output 的物理大小为零,它不使用任何数据块。

请记住,当您读取 output 文件时,空字节是由文件系统在运行时动态生成的,它们不是真正物理存储在磁盘上,并且文件的大小由 @987654337 报告@ 是逻辑大小,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 内部使用 lseekftruncate,所以检查 truncate(2) 和 lseek(2)。

【讨论】:

那么,当我们用这个方法创建一个文件时,sudo dd if=/dev/zero of=/swapfile bs=1G count=4,那么这个文件在磁盘上的大小为零?对吗? 当您使用sudo dd if=/dev/zero of=/swapfile bs=1G count=4 创建文件时,磁盘上的大小不会为零。因为dd 将零字节复制到您的文件中。换句话说,您实际上已将零字节从/dev/zero 复制到/swapfile。但是,此命令 dd if=/dev/zero of=sparse_file bs=1G seek=4 count=0 会生成一个稀疏文件,您可以在两个文件上运行 stat 并查看 Blocks 字段如何更改。您的命令是制作交换文件的推荐方法。 如果你运行fallocate -d /swapfile,这个命令就地生成一个交换文件,删除所有分配给/swapfile的空字节数据块。同样,您可以在运行 fallocate 命令后使用 stat /swapfile 检查,看看分配的块数会发生什么变化。但是,不要对交换文件执行此操作,请在另一个文件上进行测试。 @Luv33preet 我已经编辑了我的答案。它们是存储在磁盘上的孔(只是稀疏的零),因此文件不是稀疏的。稀疏文件通过不在磁盘上存储稀疏零来有效地使用磁盘空间。 @direprobs 我试图编辑您的最后一个示例以匹配您的评论。答案中的文字没有按预期工作。但是修改被拒绝了。请批准修改或自行修改,我确定这只是复制粘贴错误。【参考方案2】:

稀疏文件是一个大部分为空的文件,即它包含大块字节,其值为0(零)。

在磁盘上,文件的内容存储在固定大小的块中(通常为 4 KiB 或更大)。当这样一个块中包含的所有字节都是0时,实现稀疏文件的文件系统不会将该块存储在磁盘上,而是将信息保存在文件元数据中的某个位置。

使用稀疏文件的好处:

空数据块不占用磁盘空间;它们不作为常规数据块存储,它们的标识符(仅使用几个字节)存储在文件元数据中;这样每个空块可以节省 4 KiB(或更多)的磁盘空间; 从稀疏文件中读取空数据块不需要时间;发生这种情况是因为没有从磁盘读取数据;由于文件系统知道块中的所有字节都是0,它只需将输入缓冲区中的所有字节设置为0,数据就准备好了;无需访问慢速存储设备; 将空数据块写入稀疏文件不需要时间;在写入时,文件系统检测到块是空的(它的所有字节都是0)并将块ID放入空块列表(在文件元数据中);没有数据写入磁盘。

有关稀疏文件的更多信息,请访问Wikipedia page。

【讨论】:

以上是关于什么是稀疏文件,我们为什么需要它?的主要内容,如果未能解决你的问题,请参考以下文章

DeepRec 大规模稀疏模型训练推理引擎

什么是稀疏文件(Sparse File)

为什么L1稀疏,L2平滑?

压缩感知合集6压缩感知为什么可以恢复信号;为什么需要满足稀疏性条件RIP条件矩阵不相关等限制条件才可以恢复信号的逻辑分析

压缩感知合集6压缩感知为什么可以恢复信号;为什么需要满足稀疏性条件RIP条件矩阵不相关等限制条件才可以恢复信号的逻辑分析

稀疏矩阵减法