Skip to content

S3 Resumable Migration Version 2 ( S3 断点续传迁移 Version 2)

License

Notifications You must be signed in to change notification settings

aws-samples/amazon-s3-resumable-upload

Amazon S3 Resumable Transfer V2 (Amazon S3 断点续传传输 V2)

English README: README.en.md

多线程断点续传,适合批量的大文件S3上传/下载本地/跨对象存储迁移,支持Amazon S3, Ali OSS, Tencent COS, Google GCS, HuaweiCloud 等兼容S3 API的对象存储 本 Version 2 在同一个应用通过配置即可用做各种场景:单机的上传,单机的下载,部署为集群版的扫描源文件,或作为集群版的分布式传输工作节点;用Golang做了重构,提高性能;支持了一系列扩展功能:排除列表、源no-sign-request、源request-payer、目的storage-class、目的ACL、传输 Metadata 等。

img img

功能

  • 多线程并发传输到多种对象存储,断点续传,自动重传。多文件任务并发,充分利用带宽。优化的流控机制。在一次集群测试中(10台m5.large),迁移1.2TB数据从 us-east-1 到 cn-northwest-1 只用1小时。在另一个单机带宽的测试中,同 Region 的两个 S3 用 m6i.8xlarge EC2 传输 (num-workers 16),跑出了单机持续 12Gbps 的传输速度。

  • 支持的源和目的地:本地目录或单个文件, Amazon S3, Ali OSS, Tencent COS, Google GCS 等对象存储。无需区分工作模式,指定好源和目的URL或本地路径即可自动识别并开始传输。可以是单个文件或对象,或整个目录,或S3桶/前缀等URL。

  • 传输数据只以单个分片的形式过中转节点的内存,不落盘到节点,节省时间且更安全。可支撑 0 Size 至 TB 级别 。

  • 支持设置目的地的各种对象存储级别,如:STANDARD|REDUCED_REDUNDANCY|STANDARD_IA|ONEZONE_IA|INTELLIGENT_TIERING|GLACIER|DEEP_ARCHIVE|OUTPOSTS|GLACIER_IR|SNOW

  • 支持指定目的S3的ACL: private|public-read|public-read-write|authenticated-read|aws-exec-read|bucket-owner-read|bucket-owner-full-control

  • 支持设置源对象存储是no-sign-request和request-payer

  • 支持源对象是 Presign URL 或 URL 列表(注意生成Presign URL的时候指定 Bucket 正确的 Region)

  • 支持获取源对象存储的 Metadata 也复制到目的对象存储。但要注意这个需要每个对象都Head去获取一次,会影响性能和增加对源S3的请求次数费用。

  • 自动对比源/目的桶的文件名和大小,不一致的才传输。默认是一边List,一边传输,即逐个获取目的对象信息对比一个就传输一个,这样使用体验是输入命令之后就立马启动传输(类似AWS CLI);可选设置 -l 参数,为List目的对象列表之后再进行传输,因为List比逐个Head对比效率更高,也节省请求次数的费用。

  • 本次 Version 2 支持了多线程并行 List ,对于对象数量很多的情况,可以更快完成List。例如3千万对象的桶,如果按正常 List(例如 aws s3 ls)要90分钟以上,而现在在使用64并发的情况(16vCPU)下缩减到只有 1 到 2 分钟。

  • 支持把对比扫描出来的任务列表存入文件;支持把已发送到SQS的日志存入文件;支持设置排除列表,如果数据源Key或源本地路径符合排除列表的则不传输;支持DRYRUN模式,只比较源和目的桶,统计数量和Size,不传输数据;支持不做对比不检查目的对象,直接覆盖的模式。

  • 支持设置断点续传阈值;设置并行线程数;设置请求超时时间;设置最大重试次数;支持设置是否忽略确认命令,直接执行;

使用说明

安装Go运行环境

首次使用需要安装Golang运行环境,以Linux为例:

sudo yum install -y go git -y

如果在中国区,可通过go代理来下载go依赖包,则多运行一句代理设置:

go env -w GOPROXY=https://goproxy.cn,direct   

下载和编译本项目的Go代码

git clone https://github.com/aws-samples/amazon-s3-resumable-upload
cd amazon-s3-resumable-upload
go build .  # 下载依赖包并编译程序

可使用 ./s3trans -h 获取帮助信息

使用

  • 下载S3文件到本地:
./s3trans s3://bucket-name/prefix /local/path 
# 以上是使用默认AWS profile in ~/.aws/credentials,如果是EC2且没有配置 profile 而是使用IAM Role,需指定一下 Region
./s3trans s3://bucket-name/prefix /local/path --from-region=my_region
# 如果要指定S3的profile则如下:
./s3trans s3://bucket-name/prefix /local/path --from-profile=source_profile
  • 上传本地文件到S3:
./s3trans /local/path s3://bucket-name/prefix
# 以上是使用默认AWS profile in ~/.aws/credentials,如果是EC2且没有配置 profile 而是使用IAM Role,需指定一下 Region
./s3trans /local/path s3://bucket-name/prefix  --to-region=my_region
# 如果要指定S3的profile则如下:
./s3trans /local/path s3://bucket-name/prefix --to-profile=dest_profile
  • 从S3到S3,如不指定region,则程序会先自动查询Bucket的Region:
./s3trans s3://bucket-name/prefix s3://bucket-name/prefix --from-profile=source_profile --to-profile=dest_profile
# 如果from-profile不填则获取默认的profile或使用EC2 IAM Role,需指定一下region
./s3trans s3://bucket-name/prefix s3://bucket-name/prefix --from-region=my_region --to-profile=dest_profile
  • 对于非AWS的S3兼容存储,则需要指定endpoint
./s3trans s3://bucket-gcs-test s3://bucket-virginia --from-profile=gcs_profile --to-profile=aws_profile --from-endpoint=https://storage.googleapis.com
# 以上endpoint也可以用简称替换,即:--from-endpoint=google_gcs,还可以是其他简称:ali_oss, tencent_cos, azure_blob(TODO: azure)
  • -l 指定先List再同步数据(节省请求次数费用,但会增加一次List的时间)
  • -n (n 即NumWorkers)指定并行List和并行传输线程数。最大并发对象数为n,每个对象最大并发为2n,List Bucket时最大并发为4n;推荐n <= vCPU numbe
  • -y 忽略确认命令,直接执行
./s3trans C:\Users\Administrator\Downloads\test\ s3://huangzb-virginia/win2/ --to-profile sin  -l -n 8 -y
  • 支持设置排除列表 (--ignore-list-path) 如果数据源的S3 Key或源本地路径符合排除列表的则不传输 例如,排除列表路径设置为 --ignore-list-path="./ignore-list.txt" 文件内容为:
test2/
test1

则源数据中遇到这些路径都会被跳过,不传输:test2/abc.zip, test1/abc.zip, test1, test1.zip, test2/cde/efg等... 而这些路径则会正常传输,因为开头Prefix不一致:test3/test1, test3/test2/ 等...

集群模式

集群模式的 List 模块使用

对比源Bucket/Prefix和目的Bucket/Prefix,把不一致的对象信息写入SQS队列,以便后续的传输节点使用。
需要指定源S3和目的S3的URL,另还需要指定一个SQS用于发送任务列表,包括SQS的url和能访问这个SQS所用的AWS profile。不指定 sqs profile 则程序会自动从 EC2 IAM Role 获取权限,Region名称会从sqs-url自动提取。
可选:
设置把对比扫描出来的任务列表存入文件 --joblist-write-to-filepath;
设置把SQS发送的日志存入文件 --sqs-log-to-filename

./s3trans s3://from_bucket/ s3://to_bucket/prefix --from-profile us --to-profile bjs \
    --work-mode SQS_SEND
    --sqs-profile us \
    --sqs-url "https://sqs.region.amazonaws.com/my_account_number/sq_queue_sname" \
    --joblist-write-to-filepath "./my_joblist.log" \
    --sqs-log-to-filename  "./sqssent.log" \
    -y -l -n 8

集群模式的传输节点使用

从SQS队列中获取任务列表,然后传输数据。需要指定源S3和目的S3的URL,另还需要指定一个SQS用于发送任务列表,包括SQS的url和能访问这个SQS所用的AWS profile。不指定 sqs profile 则程序会自动从 EC2 IAM Role 获取权限,Region名称会从sqs-url自动提取。

./s3trans s3://from_bucket/prefix s3://to_bucket/ --from-profile us --to-profile bjs \
    --work-mode SQS_CONSUME
    --sqs-profile us \
    --sqs-url "https://sqs.region.amazonaws.com/my_account_number/sq_queue_sname" \
    -y -l -n 8

下载从 Presign URL 或 URL 列表

多线程并发下载单一个 URL (presign url)

./s3trans "https://your_bucket.s3.region.amazonaws.com/prefix/filename?X-Amz-Algorithm=xxxx&&X-Amz-Credential=xxxx&&X-Amz-Date=xxxx&&X-Amz-Expires=xxxx&X-Amz-SignedHeaders=host&X-Amz-Signature=xxxx" /localpath_download_to/

多线程并发按照 URL 列表下载,下例子中 URL 列表文件名为 list_file.txt,文件中每行为一个 presign URL

./s3trans /mypath/list_file.txt /localpath_download_to/
    --work-mode HTTP_DOWNLOAD_LIST

其他使用帮助

./s3trans -h

s3trans 从源传输数据到目标
./s3trans FROM_URL TO_URL [OPTIONS]
FROM_URL: 数据源的URL,例如 /home/user/data or s3://bucket/prefix
TO_URL: 传输目标的URL,例如 /home/user/data or s3://bucket/prefix

Usage:
s3trans FROM_URL TO_URL [flags]

Flags:  
      --acl string                目标S3桶的ACL,private表示只有对象所有者可以读写,例如 private|public-read|public-read-write|authenticated-read|aws-exec-read|bucket-owner-read|bucket-owner-full-control ,不设置则默认根据S3的默认设置,通常是 private 模式 
      --from-endpoint string      数据源的 API Endpoint 例如 https://storage.googleapis.com; https://oss-shenzhen.aliyuncs.com; https://cos.<region>.myqcloud.com 如果是AWS S3或本地路径,无需指定这个 Endpoint  
      --from-profile string       数据源在~/.aws/credentials中的AWS profile,如果不指定profile则用default profile,如果没有default profile,则需指定region  
      --force-path-style          设置为true时,可强制请求使用路径样式寻址,而不是域名。参考:http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
      --from-region string        数据源的区域,例如 cn-north-1. 如果未指定,但有设置 profile 则会自动找S3的所在 Region  
  -h, --help                      帮助文档  
      --http-timeout int          API请求超时(秒)(默认30)  
  -l, --list-target               推荐使用。列出目标S3桶,传输之前先比较现有对象。因为列表方式比逐个对象请求检查是否存在更有效率,只是因为需要等待列出所有对象进行比较,然后再开始传输所以感觉启动较慢。为了缓解这个问题,此应用程序利用多线程并行List,进行快速列表;如果没有设置--list-target参数,就不List目标S3桶了,而是在传输每个对象之前,检查每个目标对象,这会消耗更多API调用,但开始更快;如果完全不希望做对比,直接覆盖,则用下面提到的--skip-compare参数,而不用--list-target了; 
      --max-retries int           API请求最大重试次数(默认5)  
      --no-sign-request           源桶不需要请求签名(即允许匿名)的情况  
  -n, --num-workers int           NumWorkers x 1 个并发线程传输文件;NumWorkers x 2 每个文件的并发分片同时传输的线程数;NumWorkers x 4 List目标桶的并发线程数;推荐NumWorkers <= vCPU数量(默认4)  
      --request-payer             源桶要求请求者支付的情况  
      --resumable-threshold int   当文件大小(MB)大于此值时,使用断点续传。(默认50)  
  -s, --skip-compare              跳过比较源和目标S3对象的名称和大小。直接覆盖所有对象。不列出目标也不检查目标对象是否已存在。  
      --sqs-profile string        work-mode为SQS_SEND或SQS_CONSUME的场景下,为访问SQS队列使用~/.aws/credentials中的哪个AWS profile,不指定sqs profile则程序会自动从EC2 IAM Role获取权限,Region名称会从sqs-url自动提取。  
      --sqs-url string            work-mode为SQS_SEND或SQS_CONSUME的场景下,指定发送或消费消息的SQS队列URL,例如 https://sqs.us-east-1.amazonaws.com/my_account/my_queue_name  
      --storage-class string      目标S3桶的存储类,例如 STANDARD|REDUCED_REDUNDANCY|STANDARD_IA|ONEZONE_IA|INTELLIGENT_TIERING|GLACIER|DEEP_ARCHIVE|OUTPOSTS|GLACIER_IR|SNOW 或其他S3兼容的  
      --to-endpoint string        数据传输目标的端点,例如 https://storage.googleapis.com . 如果是AWS S3或本地路径,无需指定这个  
      --to-profile string         数据传输目标在~/.aws/credentials中的AWS profile,如果不指定profile则用default profile,如果没有default profile,则需指定region    
      --to-region string          数据传输目标的区域,例如 cn-north-1. 如果未指定,但有设置 profile 则会自动找S3的所在 Region  
      --transfer-metadata         从源S3桶获取元数据并上传到目标对象。这需要每传输一个对象都通过API调用获取源文件元数据。  
      --work-mode string          SQS_SEND | SQS_CONSUME | DRYRUN | HTTP_DOWNLOAD_LIST; SQS_SEND:扫描节点,表示列出源S3和目标S3进行比较,并发送传输任务消息到SQS队列;SQS_CONSUME: 工作节点,表示从SQS队列获取任务消息并从来源S3传输对象到S3; HTTP_DOWNLOAD_LIST:从一个文件中的 presign url 列表(即一个http列表)下载;  
  -y, --y                         忽略等待确认,直接执行;DRYRUN是只比较源和目的桶,统计数量和Size,不传输数据  

其他说明

S3 触发 SQS 的 Policy示例

写入SQS权限:"Service": "s3.amazonaws.com" 读取SQS权限:EC2 Role 或直接填 AWS Account Number

{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__owner_statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::my_account_number:root"
      },
      "Action": "SQS:*",
      "Resource": "arn:aws:sqs:us-west-2:my_account_number:s3_migration_queque"
    },
    {
      "Sid": "__sender_statement",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:us-west-2:my_account_number:s3_migration_queque"
    },
    {
      "Sid": "__receiver_statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::my_account_number:root"
      },
      "Action": [
        "SQS:ChangeMessageVisibility",
        "SQS:DeleteMessage",
        "SQS:ReceiveMessage"
      ],
      "Resource": "arn:aws:sqs:us-west-2:my_account_number:s3_migration_queque"
    }
  ]
}

配置文件

如果不使用上面的命令行参数,而使用配置文件,可以在程序运行目录下写一个config.yaml文件,内容如下。然后只需要运行 ./s3trans FROM_URL TO_URL 即可。

from-profile: "your_from_profile"
to-profile: "your_to_profile"
from-endpoint: "your_from_endpoint"
to-endpoint: "your_to_endpoint"
from-region: "your_from_region"
to-region: "your_to_region"
storage-class: "your_storage_class"
acl: "your_acl"
no-sign-request: false
request-payer: false
db-location: "./your_download_status.db"
list-target: false
skip-compare: false
transfer-metadata: false
http-timeout: 30
max-retries: 5
retry-delay: 5
chunk-size: 5
resumable-threshold: 50
num-workers: 4
y: false
work-mode: "your_work_mode"
sqs-url: "your_sqs_url"
sqs-profile: "your_sqs_profile"
joblist-write-to-filepath: "your_joblist_write_to_filepath"
sqs-log-to-filename: "your_sqs_log_to_filename"
ignore-list-path: "your_ignore_list_path"

还可以把以上配置写入环境变量。

License

This library is licensed under the MIT-0 License. See the LICENSE file.


Author: Huang, Zhuobin (James)


About

S3 Resumable Migration Version 2 ( S3 断点续传迁移 Version 2)

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages