在 Linux 上存储和备份 1000 万个文件

Ben*_*rel 26 linux storage filesystems ext4 ext3

我运行一个网站,其中大约 1000 万个文件(书籍封面)存储在 3 个级别的子目录中,范围为 [0-f]:

0/0/0/
0/0/1/
...
f/f/f/
Run Code Online (Sandbox Code Playgroud)

这导致每个目录大约有 2400 个文件,这在我们需要检索一个文件时非常快。这也是许多问题建议的做法。

但是,当我需要备份这些文件时,仅浏览包含 10m 文件的 4k 目录就需要很多天。

所以我想知道我是否可以将这些文件存储在一个容器(或 4k 容器)中,每个文件系统都完全像一个文件系统(某种安装的 ext3/4 容器?)。我想这几乎与直接访问文件系统中的文件一样有效,并且这将具有非常有效地复制到另一台服务器的巨大优势。

关于如何做到最好的任何建议?或者任何可行的替代方案(noSQL,...)?

Set*_*son 12

用于快速访问和备份数百万个文件的选项

向有类似问题的人借用

这听起来很像 USENET 新闻服务器和缓存 Web 代理所面临的一种更简单的问题:数亿个随机访问的小文件。您可能想从他们那里得到一些提示(除非他们通常不必进行备份)。

http://devel.squid-cache.org/coss/coss-notes.txt

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=4074B50D266E72C69D6D35FEDCBBA83D?doi=10.1.1.31.4000&rep=rep1&type=pdf

显然,循环新闻文件系统的循环性质与您无关,但是具有多个磁盘文件/设备和打包图像以及用户提供的用于查找位置信息的信息的快速索引的较低级别概念非常合适。

专用文件系统

当然,这些只是类似于人们所谈论的在文件中创建文件系统并通过环回挂载的概念,除非您可以编写自己的文件系统代码。当然,既然你说你的系统主要是读取,你实际上可以将一个磁盘分区(或 lvm 分区以灵活调整大小)专用于这一目的。当您要备份时,将文件系统挂载为只读,然后复制分区位。

LVM

我在上面提到 LVM 可用于允许动态调整分区大小,这样您就不需要备份大量空白空间。但是,当然,LVM 具有其他可能非常适用的功能。特别是“快照”功能,可让您随时冻结文件系统。任何意外rm -rf或任何事情都不会干扰快照。完全取决于您要执行的操作,这可能足以满足您的备份需求。

RAID-1

我相信您已经熟悉 RAID 并且可能已经使用它来提高可靠性,但是 RAID-1 也可以用于备份,至少如果您使用的是软件 RAID(您可以将它与硬件 RAID 一起使用,但实际上降低可靠性,因为它可能需要相同的模型/修订控制器才能读取)。这个概念是,您创建一个 RAID-1 组,其中的磁盘比正常可靠性需求实际需要连接的磁盘多(例如,如果您使用带有两个磁盘的软件 RAID-1,或者可能是一个大磁盘和一个硬件,则创建第三个磁盘)具有较小磁盘的 RAID5,在硬件 RAID-5 之上具有软件 RAID-1)。当需要备份时,安装一个磁盘,要求 mdadm 将该磁盘添加到 raid 组中,等到它指示完成时,可以选择要求进行验证清理,然后删除该磁盘。当然,


小智 9

您可以使用环回管理器挂载虚拟文件系统,但这虽然会加快备份过程,但可能会影响正常操作。

另一种选择是使用 dd 备份整个设备。例如,dd if=/dev/my_device of=/path/to/backup.dd

  • 如果您使用这种方法,您应该测试恢复(好吧,您应该始终这样做),因为如果您的输入是像 /dev/sdd 这样的磁盘,dd 将存储分区方案和大小。如果将其恢复到较小的磁盘,则会出现错误,如果将其恢复到较大的磁盘,则会显示为截断。如果您将数据恢复到相同磁盘类型的另一个示例,它将效果最佳。仅恢复分区 (/dev/sdd1) 会不那么麻烦。 (3认同)

Nem*_*emo 9

您可能知道,您的问题是局部性。典型的磁盘寻道需要 10 毫秒左右。因此,仅对 1000 万个随机放置的文件调用“stat”(或 open())就需要 1000 万次搜索,或大约 100000 秒或 30 小时。

因此,您必须将文件放入更大的容器中,这样相关的数字就是您的驱动器带宽(单个磁盘通常为 50-100 MB/秒),而不是您的寻道时间。此外,您还可以使用 RAID 来增加带宽(但不会减少寻道时间)。

我可能不会告诉你任何你还不知道的事情,但我的观点是你的“容器”想法肯定会解决问题,几乎任何容器都可以。环回挂载可能会像任何东西一样工作。


sys*_*138 5

有几个选项。最简单的并且应该适用于所有 Linux 文件系统的方法是dd将整个分区(/dev/sdb3/dev/mapper/Data-ImageVol)复制到单个映像并存档该映像。在恢复单个文件的情况下,环回挂载映像 ( mount -o loop /usr/path/to/file /mountpoint) 并复制您需要的文件。对于完整分区还原,您可以反转初始dd命令的方向,但您确实需要一个大小相同的分区。

从您的用例来看,我猜单个文件还原是一个非常罕见的事件,如果它们曾经发生过的话。这就是基于图像的备份在这里真正有意义的原因。如果您确实需要更频繁地进行单个还原,则使用分阶段 LVM 快照会方便得多;但是您仍然需要为那些严重的“我们失去一切”灾难进行基于映像的备份。基于图像的恢复往往走了不少不是基于焦油的恢复仅仅是因为它只是恢复块,它不在产生相当多的元数据操作的每FOPEN / FCLOSE更快,也可以是一个高度连续盘操作进一步提高速度。

或者,正如 Google 视频 @casey 指出的那样,大约进行到一半时,XFS 是一个很棒的文件系统(如果很复杂)。XFS 的一个更好的实用程序是xfsdump实用程序,它将整个文件系统转储到单个文件中,并且通常执行得更快tar。它是一个特定于文件系统的实用程序,因此可以以 tar 无法利用的方式利用 fs 内部结构。