侧边栏壁纸
  • 累计撰写 50 篇文章
  • 累计创建 2 个标签
  • 累计收到 4 条评论
标签搜索

目 录CONTENT

文章目录

Linux如何做到秒速复制上百G文件?

小白码上飞
2022-01-24 / 0 评论 / 0 点赞 / 575 阅读 / 2,656 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-01-24,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

摘要:主要介绍了Linux文件存储的原理,以及硬链接和软链接的区别

有点标题党了,其实主要是想讲讲Linux文件存储的原理,也就是inode,以及硬链接和软链接的区别。

话说有一个场景,数据文件存储在一个个分级的目录下,简单的描述一下,类似以下的结构:

  1. 目录1
    1. 文件1.1
    2. 文件1.2
    3. 文件1.3
  2. 目录2
    1. 文件2.1
    2. 文件2.2
  3. 目录3
    1. 文件3.1
    2. 文件3.2
  4. 目录n
    1. 文件n.1
    2. 文件n.2

我们现在想把文件1.2、文件2.1、文件3.1、文件……、文件n.1发送给其他人。最简单的方法是,将我们需要的文件都复制到同一个目录下,打包,下载到本地,或者直接复制到其他服务器上。

现在的问题是,这些数据文件很大,每个文件动辄好几g,如果每个文件都复制一份,会耗时耗空间。

大佬过来看一眼,说:你创建这些文件的硬链接到你的指定目录,不就行了?不占空间。

我说:啥?啥是硬链接?

1、文件是怎么存储的?谈谈inode和数据块

讲硬链接之前,我们需要先了解一下前置知识:Linux是怎么存储文件的。

文件自然是保存在磁盘上的,但是是以什么样的形式、什么样的结构存储的呢?

操作系统一般会将磁盘分为一个个的块(block)来读取,而这个块,就是存储文件的最小单位。一般一个块占据4k的磁盘空间。文件的数据,就会存储在磁盘的一个个块中。

而一个文件除了数据部分,还有文件自身的一些属性信息,比如:文件的大小、权限、修改创建时间、指向数据块的指针等等。这些信息叫作文件的元数据,不存储在块里,是存储在叫inode的区域中。每个inode的节点大小一般是128或256字节,且都会有一个inode号码,来唯一标识一个inode。

因此,磁盘在格式化时,会将磁盘分为两个部分:数据区和inode区。每1k或者2k的数据区,需要留存一个inode。这样的设计,正常情况下inode的数量是足够的,但是极端情况下,即便磁盘还有空间,但是inode区已经用光了,所以会导致无法创建文件。

2、读取文件过程

由以上可知,一个文件包含两部分数据:

  1. 元数据,保存在inode中。一个文件只会占用一个inode。
  2. 文件数据,保存在数据块(data block)中。一个文件因为数据量大小不同,会占用多个数据块。

inode中会保存指向数据块的指针,根据指针可以找到该文件存储的数据块。

另外,想要读取文件,这里还需要知道一个目录项(directory entry)的概念。

一个目录项会保存当前文件的文件名称和inode号码。而这个文件名称,就是你在Linux系统中看到的文件名称。

所以,你看到的文件,只是这个文件名。而对于Linux而言,它看到的文件是唯一的inode。你在读取一个文件时,Linux会通过文件名和inode号码的映射,找到inode,再根据inode保存的指针,找到文件数据存储的数据块。目录项、inode、数据块之间的关系如下:

image-20210905222126985

3、复制、硬链接和软链接

回到硬链接的话题。

比如现在有一个文件fileX,文本内容为“hehe”,我们用ll -i命令来查看一下:

image-20210905222443682

使用-i这个命令,我们可以看到文件对应的inode号码。

此时我们复制这个文件,得到结果如图:

image-20210905222642653

我们可以看到,复制出来的文件fileXBackup,他的inode号码和源文件fileX的inode号码不一样,说明我们复制了一个Linux认为的全新的文件。

再用命令ln来对文件fileX创建一个硬链接,结果如图:

image-20210905222958142

看,创建的硬链接hard,其对应的inode号码,和源文件fileX是一致的。所以对于我们来说,是创建了一个新的文件,但是对于Linux来说,还是那个inode,不多不少。

现在我们再创建一个软链接,如图:

image-20210906000412546

可以看到,软链接文件soft的inode号码,是一个新的号码,且有颜色标识和箭头指向源文件fileX。所以这个soft是一个指向fileX的文件。

现在我们尝试修改修改fileX文件,在其尾部追加文本。

echo "xixi" >> fileX

再分别查看fileXBackup、hard和soft这三个文件,如图:

image-20210914204810582

因为hard和fileX对于linux来说,都是同一个文件,自然是一样的。而soft因为指向的是fileX,因此内容也是一致的。

现在我们删除fileX,再看一下hard和soft是否还能打开。

image-20210914205003820

我们可以看到,soft指向的fileX已经被标红,且无法打开。hard依旧可以正常打开。因为删掉的只是我们眼中的fileX,而Linux眼中inode值为1838442的文件还在。

4、直接通过inode获取文件

理解了上述概念,是不是会萌生一个想法。既然Linux只认inode,那我们能不能直接通过inode找到文件呢?

实际上,如果我们知道一个文件的inode号码,则可以通过find命令,找到对应的文件,并做相应的处理。比如我们要查看上面提到的hard文件,则可以用以下命令:

find -inum 1838442

便可以查找到对应的文件。当然,我们也可以用find命令的-exec参数来直接操作该文件:

find -inum 1838442 -exec cat {} \;

结果如下:

image-20210917004210616

一般在无法处理文件名有乱码的情况下,可以使用这个方式来处理文件。

5、总结

Linux存储文件时,会将文件分为两部分。文件的数据存储到磁盘的一个或多个数据块中,文件的元数据(自身属性)存储在inode区中的一个节点上。

我们看到的文件和目录,是目录项中展示的表象。本质上想查看一个文件,需要通过目录项找到inode,再根据inode找到指向的文件数据块。站在Linux角度,一个inode才是一个文件。目录项中多个文件指向同一个inode,那也是按照同一个文件去处理。

复制、硬链接和软链接的差别:

  • 复制是创建一个目录项中的文件,指向一个新的inode,在磁盘上开辟一个新的空间。
  • 硬链接本质上是创建一个目录项中的文件,指向一个inode,还是原有的空间。
  • 软链接则是创建一个链接,指向目录项中的文件。该文件删除后,软链接自然失效了。

参考资料

https://www.kernel.org/doc/html/latest/filesystems/ext4/inodes.html

https://www.kernel.org/doc/html/latest/filesystems/ext4/ifork.html

https://www.kernel.org/doc/html/latest/filesystems/ext4/directory.html

0

评论区