亚马逊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 对本博文中的内容或准确性不承担任何责任。

Deirdré Straughan

Deirdré Straughan

Deirdré 她30年间一直在沟通技术并帮助其他人这样做了。 迄今为止她已经写作了一本书,正在编辑两本新书,制作和交付技术培训,制作了数百个视频和技术讲座直播; 写作,编辑和管理博客,以及管理各项活动。 自2010年以来,她一直将这一技能应用于云计算,并在更长的时间内应用于开源。 她于2017年6月加入 AWS,担任 AWS 开源团队的内容负责人。 你可以在Twitter @deirdres上找到她。