如果你有一个月的时间,你正在考虑的可能会奏效......但沿着这条路有陷阱。
为了解释这些,我需要有点哲学。
当面对您想要优化的资源密集型工作时,通常最好找出几个有限资源中的哪一个最适合将其推到极限,然后确保所有其他资源都足够让这种情况发生。有时,您实际上最终将一种资源推向了人为且不必要的限制。
在 1 毫秒内,一条 10 Gbit/s 的链路可以传输 10 Mbits。您浪费的每一毫秒不传输数据都会使作业的运行时间增加更多。因此,您需要保持数据流动……而您的解决方案将无法做到这一点。
S3 每秒可以轻松处理 100 次上传,如果按顺序上传,则每 10 毫秒上传 1 次……而 s3fs 不太可能跟上这一速度,而且每 10 毫秒您就可以通过链接传输 100 Mbits。 ..但你没有。您只管理了 1 个 50k 对象,或者更少。虽然 s3fs 无疑非常酷——我在一个生产后端系统的应用程序中使用它——但它也是理论上最不正确的使用 S3 的方法,因为它试图将 S3 视为文件系统......并将其暴露给具有文件系统语义的操作系统......而 S3 是对象存储,而不是文件系统,并且两者之间存在“阻抗差距”。
这里的人工阻塞点将是 s3fs,它只允许 tar 在任何给定时刻提取一个文件。tar 的输出将重复阻塞若干微秒或毫秒,等待每个对象上的 s3fs,这将阻塞 tar 从网络的输入,这将阻塞 TCP 连接,这将阻塞源 tar……意味着你实际上不会最大限度地利用您的任何实际资源,因为您达到了不必要的限制。
不要介意如果 s3fs 遇到错误会发生什么。根据错误的性质...
tar: broken pipe
哦。
你真正需要的是并发。将这些文件以 S3 接收它们的速度并行推送到 S3 中。
你最好的选择是在私有数据中心运行代码。将文件列表分成几个块。生成多个独立进程(或线程)来处理一大块文件,从磁盘读取并上传到 S3。
如果我这样做(事实上我已经这样做了),我会编写自己的代码。
但是,您可以使用 aws CLI 的aws s3 cp
命令和 gnu相当轻松地完成此操作parallel
,可以将其配置为以类似于以下方式的行为xargs
- 每个“n”个并行调用都被定向为复制构建aws s3 cp
的文件列表parallel
从标准输入并在命令行中传递。
未经测试,但在正确的轨道上...... cd
进入文件目录,然后:
$ ls -1 -f | parallel --eta -m aws s3 cp {} s3://bucket-name
ls -1 -f
列出目录中的文件,每行 1 个,仅名称,未排序,输出管道到parallel
.
--eta
根据迄今为止的进度估计剩余运行时间。
-m
意味着{}
用尽可能多的输入参数替换,同时不超过 shell 对命令行长度的限制
有关其他选项,请参阅 gnu 的文档parallel
,例如日志文件、错误处理和控制要生成的并行进程的数量(这应该默认为运行它的机器中的内核数)。只要您有可用的处理器容量和内存,您可能希望运行 2 倍、3 倍、4 倍数量的并行作业,因为有内核,否则处理器将浪费大量时间等待网络 I/O。