如何存储大量小文件

如何存储大量小文件

让我们进行以下任务:

  • 在 Linux 上备份大量(例如 500GB)的小文件(几 kB 到 1MB)
  • 备份存储是大多只读
  • 存储速度足够快,可以访问常规目录/文件视图中的特定文件,理想情况下是通过常规文件管理器(如 mc、TotalCommander(通过 samba)等)中的内置或插件功能
  • 存储最好只是单个文件(可以有效地移动到 nas 等)
  • 无需压缩
  • 添加文件可能是一个代价高昂的操作(即使是初始存储初始化)

我尝试了普通的旧方法tar,但“打开”500G 的索引似乎无止境 - 所以我可能需要将其作为一个整体提取。例如,有没有办法将dd文件系统的一部分放入映像中然后挂载它?

有什么想法吗?

答案1

您确实可以创建一个文件并将其视为块设备。不过您可能需要手动挂载它。

  1. 第一步是创建“块设备”——您可以使用dd(例如dd if=/dev/zero of=/path/to/file.name bs=100M count=6000)或其他工具(fallocatetruncate)来执行此操作。
  2. 然后,您可以使用类似以下命令来格式化设备mkfs.ext4 /path/to/file.name
  3. 接下来安装它- mkdir /mntpoint; moint /path/to/file.name /mntpoint
  4. 使用您喜欢的工具将文件复制到/mntpoint– 例如rsnapshotrsync或普通的cp
  5. 完成后卸载 – 确保您不在目录/mntpointumount /mntpoint

答案2

在需要快速访问备份内容的情况下,我会使用带选项的增量备份rsync--link-dest=
运行速度非常快,不会影响以前的备份副本(您可以拥有任意数量的备份副本),并且备份不会占用太多空间,因为备份副本是现有文件的硬链接。在这种情况下,可以即时访问备份,并且实际文件传输只需几秒钟,即使是大量文件,因为rsync只复制了新文件。

#!/bin/sh

srcDir='/importunt/data'  # Use full path
bkpDir='/backups'         # Use full path

cd "${bkpDir}"

previousDir="$(ls -td -- */ | head -n 1 | awk -F'/' '{print $1}')"   # Get most newest directory
currentDir="$(date '+%Y-%m-%dT%H;%M;%S')"

[ -n "${previousDir}" ] && {
  rsync_opts="-aPvz --safe-links --link-dest=${bkpDir}/${previousDir} --exclude=*.mp3"
} || {
  rsync_opts="-aPvz --safe-links --exclude=*.mp3"
}

mkdir -m 770 "${currentDir}"
rsync  ${rsync_opts}  "${srcDir}" "${bkpDir}"/"${currentDir}"

基本上,这样的解决方案会及时创建精确的快照,因此文件恢复非常容易。

du如果您在目录上使用时发现每次更新时大小都在增加,请不要害怕,/backups如果您使用,df您会发现实际空间并没有减少。这就是 Linux 和 FreeBSD 上硬链接的计算方式,所以不用担心。为了确保我没有撒谎,您可以使用在增量备份中检查某个文件的 inode ls -i file。您会发现所有目录中的相同文件具有相同的 inode,这意味着rsync仅重复具有硬链接的文件名,但所有文件名都指向相同的内容。

此方法的另一个优点是您可以按任何顺序删除最旧的备份目录 - 最新的、中间的或最旧的。

上述脚本是简化的示例。如果增量备份中的内容需要编辑,则您不应使用ls -t检测备份中最新的先前目录的机制,而是将其保存${currentDir}到某个文件并${previousDir}在后续调用时恢复。

由于rsync支持传输,ssh您可以以相同的效率将增量备份移动到远程机器,唯一的更改将被同步。

答案3

tar不会在文件的某个位置存储简明的索引(如 Zip)——而是用实体的数据来声明每个实体,因此“似乎永无止境“——您需要阅读整个文件以获取其中每个实体的列表。

如果您想轻松访问索引,您可以捕获的输出tar -cv,并将其与档案一起存储。

tar -cv -f ./test.tar ./to_backup/ \
    > index.txt

或者,如果您需要更多信息,您可以使用tar -cT ${FILE_LIST},它接受来自 的文件列表${FILE_LIST}。这样,您可以使用find来收集文件名,将每个文件的详细信息记录到您的“指数stdout“并生成要存档的文件名tar

find ./to_backup/ -type f \
    | tee index.txt \
    | tar -cT /dev/stdin \
    > ./test.tar

无需压缩,就可以很容易地将文件添加到档案中tartar代表“磁带档案“... 在磁带上移动数据是件很痛苦的事)。具有简洁索引的文件格式在以后添加文件会更加困难,尽管这通常是可能的。

相关内容