将数百万个文件移至S3的根

时间:2018-09-03 12:33:33

标签: php bash amazon-web-services amazon-s3 file-io

我有2000万个本地文件。每个文件都由经过哈希处理的数字ID表示。

文件1被命名为356a192b7913b04c54574d18c28d46e6395428ab(“ 1”的sha1)

文件2被命名为da4b9237bacccdf19c0760cab7aec4a8359010b0(“ 2”的sha1)

等等

不是每个数字都代表一个文件,但是我有一个列出所有数字的列表。

将文件放置在以哈希中的前两个字符命名的文件夹中,然后是后两个,然后是后两个。

对于文件1(da4b9237bacccdf19c0760cab7aec4a8359010b0),文件夹结构为

da/4b/92/

在该文件夹中放置了文件,并将其命名为完整哈希,因此文件的完整路径为

da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b0

我现在想将所有文件从文件系统移至Amazon S3的存储桶,而在执行此操作时,我要将它们移至该存储桶的根

由于文件太多,如果有一种方法可以记录哪些文件已被移动以及哪些文件可能由于某种原因而失败了,那将是一个好习惯,如果失败,我需要能够恢复操作。

我的计划是在mysql中创建一个名为moved_files的表,然后运行一个PHP脚本,该脚本从files表中获取X个ID,并使用AWS SDK for PHP复制该文件到S3,如果成功,则将该ID添加到moved_files表中。但是我不确定这是否是最快的方法,也许我应该考虑使用AWS Cli编写bash脚本。

任何建议将不胜感激!

1 个答案:

答案 0 :(得分:2)

我不使用AWS S3,但是有点谷歌搜索提示您需要这样的命令:

aws s3 cp test.txt s3://mybucket/test2.txt

因此,如果要对所有文件运行该命令,建议您使用 GNU Parallel 来充分利用连接并减少延迟。

请创建一个测试目录,其中包含几个要测试的文件,然后cd到该目录并尝试以下命令:

find . -type f -print0 | parallel -0 --dry-run aws s3 cp {} s3://rootbucket/{/}

示例输出

aws s3 cp ./da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b0 s3://rootbucket/da4b9237bacccdf19c0760cab7aec4a8359010b0
aws s3 cp ./da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b1 s3://rootbucket/da4b9237bacccdf19c0760cab7aec4a8359010b1

如果您有8个CPU内核,则一次将运行8个aws的并行副本,直到复制所有文件为止。

{}扩展为“当前文件” ,而{/}扩展为“当前文件无目录” 。您还可以添加--bar以获得进度条。

如果希望如此,我们可以为每个更新数据库或删除本地文件的文件添加一个bash函数,条件是aws命令成功执行。看起来像这样-从底部开始阅读;-)

#!/bin/bash

# bash function to upload single file
upload() {
   local="$1"                                         # Pick up parameters
   remote="$2"                                        # Pick up parameters
   echo aws s3 cp "$local" "s3://rootbucket/$remote"  # Upload to AWS
   if [ $? -eq 0 ] ; then
      : # Delete locally or update database with success
   else
      : # Log error somewhere
   fi
}

# Export the upload function so processes started by GNU Parallel can find it
export -f upload

# Run GNU Parallel on all files
find . -type f -print0 | parallel -0 upload {} {/}