文件与磁盘

磁盘与文件系统

磁盘作为一种存储介质,有自己的最小存储单位 —— 扇区。 扇区是物理划分出的存储块,存在于现实生活中,一般大小是 512 字节。

操作系统的文件系统也有自己的存储单位,叫 块。典型文件系统的块大小是 4K。

按照典型值来算,一个文件系统块包含了 8 个物理扇区, 这 8 个扇区一定是连续的, 在分区的时候就固定好了。

磁盘的物理结构长久以来都没有变化, 使用机械旋转进行寻址和读取。 机械硬盘最大转速普遍 7200转/min , 是一种比较低效的 IO 介质。

由于这种物理特性,磁盘在进行性连续读取的时候,IO性能非常好。 进行随机读取的时候,极端情况下每次读一个扇区就要寻址一次,效率很差。

注解

这种 极端情况 实际发生概率非常高。比如训练图像模型的时候, 每个图像文件很小,读取的文件顺序经过 shuffle , 就会有这种情况。

文件存储

一些特性

  • 文件一定是按照块分配空间的,对于占不满一个块的文件,也一定会单独占用一块。
    所以大量小文件会导致磁盘利用率很低。
  • 小于4K的文件,一个块就可以存储。
  • 文件大于4K, 就需要占用多个块。

碎片

分区在刚使用的时候,同一个文件占用的磁盘块、扇区都是连续的。

随着时间的推移,经常有删除旧文件的操作,会形成某个磁盘片区空闲, 而周围的磁盘块被占用的情况,类似于空洞,这种情况叫 磁盘碎片

磁盘碎片进一步导致文件存储不连续。

如果某一片区域删除了一个 8K 的旧文件,让出了空闲空间,这时候对文件系统写入一个 20K 的文件, 就需要在另外一个地方再找12K空间。这个文件就会存储在磁盘的两个不同地方。

还有另一种情况也会导致文件存储不连续。

如果有一个文件初始大小 8K, 且后方块已经存放了其他文件。然后以追加模式打开这个文件,写入其他内容。 这个时候也需要在其他地方寻找空闲块

由于文件可能存储在磁盘不同的地方,所以文件头有一个索引。

../_images/file-node.svg

文件夹不存储内容,但是要存储当前文件夹包含的文件的索引。这也是文件夹一般都占用 4K 的原因。

../_images/dir-size.jpg

对于包含文件比较多的文件夹,4K无法存储下所有文件元信息,则需要更多空间,如上图的 tmp 文件夹。

如果需要存储大量小文件( 小于 4K),也不适合用文件系统来存储,因为就算一个文件只有 1 字节, 也会至少分配 4K 的空间。但不必担心空文件,操作系统有优化,空文件并不会占用空间。

../_images/file-size.jpg

在磁盘分区的时候,可以选择块大小,块选择的大了,不利于小文件存储,但是能加速大文件 IO 性能, 块选择小了,对小文件存储有利,但是可能产生很多磁盘碎片,降低 IO 性能。 所以大数据磁盘块一般设置为 64M 这个级别。

如果要存储大量小文件,还要保证 IO 性能,可以选择把他们打包成压缩包,变成一个文件。 虽然打包成单文件并不能保证文件不会被分片,但是操作系统会尽量保证连续,分片数量更少。 另一方面,减少文件大小,也能进一步提升 IO 性能。 这样做的影响是首次读取可能很慢,类似于 Hadoop 慢启动的问题,只不过没有 Hadoop 那么严重。