我有一个S3存储桶,大约有400万个文件,总共需要500GB . 我需要将文件同步到一个新的存储桶(实际上更改存储桶的名称就足够了,但由于这是不可能的,我需要创建一个新存储桶,将文件移到那里,然后删除旧存储桶) .
我执行了'm using AWS CLI' s s3 sync
命令,但需要花费很多时间 . 我想减少时间,以便 the dependent system downtime is minimal .
我试图从我的本地机器和 EC2 c4.xlarge
实例运行同步,并且所花费的时间差别不大 .
我注意到,当我使用 --exclude
和 --include
选项分割多个批次的作业并从单独的终端窗口并行运行时,可以稍微减少所需的时间,即
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "1?/*"
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "2?/*"
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "3?/*"
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "*" --include "4?/*"
aws s3 sync s3://source-bucket s3://destination-bucket --exclude "1?/*" --exclude "2?/*" --exclude "3?/*" --exclude "4?/*"
还有什么我可以做的更快加速同步吗?另一种类型的 EC2
实例更适合这项工作吗?将作业分成多个批次是一个好主意,是否有类似于 sync
的进程可以在同一个桶上并行运行?
Update
我倾向于在关闭系统之前同步存储桶的策略,执行迁移,然后再次同步存储桶以仅复制同时更改的少量文件 . 但是,即使在没有差异的存储桶上运行相同的 sync
命令也需要花费大量时间 .
3 回答
作为OP已经在做什么的变种..
可以创建一个要同步的所有文件的列表,使用
aws s3 sync --dryrun
使用要同步的对象列表,将作业拆分为多个
aws s3 cp ...
命令 . 通过这种方式,"aws cli"不会只是挂在那里,同时获取同步候选列表,就像使用--exclude "*" --include "1?/*"
类型参数启动多个同步作业时一样 .完成所有"copy"作业后,如果对象可能会从"source"存储桶中删除,那么另一个同步可能是值得的,可能是
--delete
.如果"source"和"destination"桶位于不同的区域,则可以在开始同步存储桶之前启用cross-region存储桶复制 .
您可以使用EMR和S3-distcp . 我不得不在两个桶之间同步153 TB,这需要大约9天 . 还要确保存储桶位于同一区域,因为您也会遇到数据传输成本 .
http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html
http://docs.aws.amazon.com/ElasticMapReduce/latest/ReleaseGuide/emr-commandrunner.html
背景:sync命令中的瓶颈是列出对象和复制对象 . 列表对象通常是一个串行操作,但如果指定前缀,则可以列出对象的子集 . 这是并行化的唯一技巧 . 复制对象可以并行完成 .
不幸的是,
aws s3 sync
不支持按前缀列出,除非前缀在/
结束(即,它可以按文件夹列出) . 这就是它如此缓慢的原因 .s3s3mirror(和许多类似的工具)并行化复制 . 我不认为它(或任何其他工具)并行化列表对象,因为这需要先验知道如何命名对象 . 但是,它确实支持前缀,您可以为字母表中的每个字母(或任何适当的字母)多次调用它 .
您也可以使用AWS API自行滚动 .
最后,如果您在与S3存储桶相同的区域中的实例中启动它,那么
aws s3 sync
命令本身(以及任何相关工具)应该会更快一些 .