![快速访问和备份数百万个文件的选项](https://linux22.com/image/550881/%E5%BF%AB%E9%80%9F%E8%AE%BF%E9%97%AE%E5%92%8C%E5%A4%87%E4%BB%BD%E6%95%B0%E7%99%BE%E4%B8%87%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E9%80%89%E9%A1%B9.png)
我运营一个网站,其中大约有 1000 万个文件(书籍封面)存储在 3 级子目录中,范围为 [0-f]:
0/0/0/
0/0/1/
...
f/f/f/
这样每个目录就有大约 2400 个文件,当我们需要检索一个文件时,这个速度非常快。此外,这也是许多问题。
但是,当我需要备份这些文件时,仅浏览包含 10m 文件的 4k 目录就需要花费很多天的时间。
因此,我想知道是否可以将这些文件存储在一个容器(或 4k 容器)中,每个容器的行为都与文件系统完全相同(某种已安装的 ext3/4 容器?)。我猜这几乎与直接访问文件系统中的文件一样高效,并且这样做的一大优势是可以非常高效地复制到另一台服务器。
关于如何最好地做到这一点,您有什么建议吗?或者有任何可行的替代方案(noSQL,...)?
答案1
快速访问和备份数百万个文件的选项
向有类似问题的人借钱
这听起来很像 USENET 新闻服务器和缓存网络代理面临的一个更简单的问题:数亿个随机访问的小文件。您可能想从他们那里得到一些提示(除了他们通常不需要备份)。
http://devel.squid-cache.org/coss/coss-notes.txt
显然,循环新闻文件系统的循环性质与您无关,但拥有多个带有打包图像的磁盘文件/设备以及从用户提供的信息中查找位置信息的快速索引的较低级别概念非常合适。
专用文件系统
当然,这些概念与人们谈论的在文件中创建文件系统并通过回送挂载它的概念类似,只不过您可以编写自己的文件系统代码。当然,既然您说您的系统主要是读取的,那么您实际上可以将一个磁盘分区(或 lvm 分区,以便灵活调整大小)专用于此目的。当您想要备份时,请以只读方式挂载文件系统,然后复制分区位。
逻辑卷管理器
我上面提到 LVM 很有用,因为它允许动态调整分区大小,这样您就不需要备份大量空白空间。但是,当然,LVM 还有其他可能非常适用的功能。特别是“快照”功能,它允许您在某个时刻冻结文件系统。任何意外rm -rf
或其他情况都不会干扰快照。根据您要执行的操作,这可能足以满足您的备份需求。
RAID-1
我确信您已经熟悉 RAID,并且可能已经将其用于可靠性,但 RAID-1 也可用于备份,至少在您使用软件 RAID 的情况下(您可以将其与硬件 RAID 一起使用,但这实际上会降低可靠性,因为它可能需要相同的型号/版本控制器才能读取)。概念是,您创建一个 RAID-1 组,其中的磁盘比您实际需要连接的磁盘多一个,以满足您的正常可靠性需求(例如,如果您使用带有两个磁盘的软件 RAID-1,则需要第三个磁盘,或者可能是一个大磁盘和一个带有较小磁盘的硬件 RAID5,在硬件 RAID-5 之上使用软件 RAID-1)。当需要进行备份时,安装磁盘,让 mdadm 将该磁盘添加到 raid 组,等到它指示完整,可以选择要求进行验证清理,然后移除磁盘。当然,根据性能特征,您可以大多数时候都安装磁盘,只在与备用磁盘交换时移除,或者您可以只在备份期间安装磁盘)。
答案2
您可以使用环回管理器挂载虚拟文件系统,但虽然这会加快您的备份过程,但可能会影响正常操作。
另一种方法是使用 dd 备份整个设备。例如,dd if=/dev/my_device of=/path/to/backup.dd
。
答案3
您可能知道,您的问题在于局部性。典型的磁盘寻道大约需要 10 毫秒。因此,仅对 1000 万个随机放置的文件调用“stat”(或 open())就需要 1000 万次寻道,即大约 100000 秒或 30 小时。
因此,您必须将文件放入更大的容器中,这样相关的数字就是您的驱动器带宽(单个磁盘通常为 50-100 MB/秒),而不是您的寻道时间。此外,您还可以为其添加 RAID,这可以让您提高带宽(但不会减少寻道时间)。
我可能没有告诉你任何你不知道的事情,但我的观点是你的“容器”想法肯定会解决问题,而且几乎任何容器都可以。环回安装可能和其他任何东西一样好用。