亚马逊AWS官方博客
OpenSource | 通过 s5cmd 在 S3 上处理多个对象任务
此开源项目来自我们的客户社区。此项目由 Peak Games 开发,用于为其自己的 S3 工作流程提供帮助,该项目包含 Tab 补全以及支持在 S3 命令中对文件使用内置通配符等诸多功能。希望您能喜欢!- Deirdré
背景
到目前为止,通过命令行在 Amazon S3 上处理多个对象意味着,使用可提供一定支持的工具调用多个命令或者使用通配符。每次命令调用都相当于在系统级别执行了另一次 fork/exec,当您需要运行几百项或更多的操作时,其开销会累加。
工具
通过 s5cmd,调用一个可执行文件便可运行多个操作 (使用/不使用通配符)。例如,如果您必须删除 (或复制) 几百万个对象,则无需几百万次地调用 CLI 工具。通过将命令发送到 s5cmd,您只需调用该工具一次,然后让其运行几百个工作线程来执行给定的工作。由于 s5cmd 已经有工作线程池,因此可以将一个工作线程用于 ListObjects 调用 (可以匹配更多通配符) 来完成通配符操作,然后让其他工作线程执行实际处理操作。它还支持自动补齐 bash 和 zsh 的 shell,因此,如果您想将其用作较为常用的 CLI 工具,可以仅单击 TAB 键,让其自动为您补齐选项、存储桶以及路径/对象。
安装
在 Mac OS X 上安装 s5cmd:
$ brew tap peakgames/s5cmd https://github.com/peakgames/s5cmd
$ brew install s5cmd
该工具使用 Go 编写,其他平台可以使用以下命令对其进行编译和安装:
$ go get -u github.com/peakgames/s5cmd
像使用 awscli 工具时那样设置凭证:使用 ~/.aws/credentials 文件和/或环境变量。(如果在 EC2 上运行,还支持角色。)
使用
命令采用“command [command options] argument1 [argument2]”格式。s5cmd 也会采用选项,这会影响运行的所有命令。要获取 s5cmd 选项列表,请运行以下命令:
$ s5cmd -help
要获取可用命令列表,请在不指定任何参数的情况运行:
$ s5cmd
s5cmd 实际应用
假设有一个名为“reports-bkt”的存储桶,其内部有一些文件。首先,我们下载一个文件:
$ s5cmd get s3://reports-bkt/a/2018/03/14/reports_19_13716285583145.csv.gz
# Downloading reports_19_13716285583145.csv.gz...
2018/03/21 11:46:05 +OK "get s3://reports-bkt/a/2018/03/14/reports_19_13716285583145.csv.gz ./reports_19_13716285583145.csv.gz"
现在,我们扫描上个月的所有 CSV 报告,并用通配符匹配每天的报告:
$ s5cmd du -g -h s3://reports-bkt/a/2018/02/*/reports*csv.gz
+ 10.7M bytes in 367 objects: s3://reports-bkt/a/2018/02/*/reports*csv.gz [STANDARD]
2018/03/21 11:46:24 +OK "du s3://reports-bkt/a/2018/02/*/reports*csv.gz" (1)
上个月有 367 份报告,占用了大约 10MB 的空间,所有报告均使用标准存储。我们将其全部下载下来:
$ s5cmd cp --parents s3://reports-bkt/a/2018/02/*/reports*csv.gz .
使用 --parents
选项,上个月每天的报告将下载到其自己的目录下。(此选项会从指定的第一个通配符开始创建目录结构。)上述示例只是冰山一角。另一种选项是使用文件或其他命令的输出来发送命令。您可能已经发现,我们的存储桶采用常见的“字母前缀”模式。假设您要下载给定日期的所有文件用于所有前缀。结构如下所示:
- a/[yyyy]/[mm]/[dd]/object_unique_id.gz
- b/[yyyy]/[mm]/[dd]/object_unique_id.gz
- c/[yyyy]/[mm]/[dd]/object_unique_id.gz
... up to ...
- z/[yyyy]/[mm]/[dd]/object_unique_id.gz
如果您有几百天时间和几十亿个对象,在第一级指定通配符实际上不起作用。由于您已经知道范围 (字母 a 到 z),您可以为每个前缀生成命令。仅调用该工具一次,然后让它完成工作。试试:
$ for X in {a..z}; do echo get -n s3://reports-bkt/${X}/2018/03/14/reports*csv.gz; done | s5cmd -f -
2018/03/21 11:48:03 # Stats: Total 379 281 ops/sec 1.350311978s
第一个命令将生成大量“get”命令,然后将这些命令传递到 s5cmd 完成工作。请注意,我们使用了“-n”(no-clobber) 选项,以防在对象名称并不真正唯一的情况下出现改写。我们不能使用 --parents
选项,因为通配符不在目录名称中。您可以查看 stat 计数器来了解完成的操作数目 (以及所用的时间)。
投稿
欢迎大家为该项目献言献策,所有来稿均使用 github.com/peakgames/s5cmd 处的问题跟踪器进行管理。如果您要提交 PR,我们建议您先提出问题,以便与团队进行讨论。
本客座博文来自 Peak Games,该公司使用 S3 作为将数据转化成知识的综合管道的一部分,从而进一步改善其世界一流的手机游戏的用户体验。本博文中的内容和观点均源自第三方作者,AWS 对本博文中的内容或准确性不承担任何责任。