ablog

不器用で落着きのない技術者のメモ

S3 to S3 でストリーミング圧縮コピーする(boto3版)

AWS CLI で S3 to S3 で圧縮してストリーミングコピーしたい場合は aws s3 cp s3://... - | gzip | aws s3 cp - s3://...S3 からローカルにファイルをまるまるダウンロードせずに圧縮して S3 にアップロードする - ablog) のようにパイプで繋げばよいが、Python で書きたい場合は smart_open パッケージを使うとできる。

準備

  • 環境
$ cat /etc/system-release
Amazon Linux release 2023 (Amazon Linux)
 uname -r
6.1.52-71.125.amzn2023.x86_64
$ pyenv versions
  system
  2.7.18
* 3.10.13 (set by /home/ec2-user/.pyenv/version)
  • パッケージのインストール
$ pip install smart_open
$ pip install boto3
  • EC2 に以下の権限を持つ IAM ロールをアタッチする
    • Permissions
      • AmazonS3FullAccess
    • Trust relationships
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

サンプルコード

  • s3_streaming_copy.py
from smart_open import open, register_compressor
import boto3

session = boto3.Session()
src_path = 's3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat'
dst_path = 's3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz'

with open(dst_path, 'wb', transport_params={'client': session.client('s3')},  compression='.gz') as fout:
    with open(src_path, 'rb', transport_params={'client': session.client('s3')}) as fin:
        for s_line in fin:
            fout.write(s_line)

実行

  • テストデータを作成して S3 にアップロードする
$ dd if=/dev/zero of=1gb.dat bs=1M count=1024
$ aws s3 cp 1gb.dat s3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat
$ aws s3 ls --human-readable s3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat
2023-10-04 09:57:34    1.0 GiB 1gb.dat
  • 実行する
$ python s3_streaming_copy.py
  • 結果の確認
$ aws s3 ls --human-readable s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz
2023-10-04 09:57:56 1019.2 KiB 1gb.gz
 aws s3 cp s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz ./
download: s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz to ./1gb.gz
$ file 1gb.gz
1gb.gz: gzip compressed data, was "1gb", last modified: Wed Oct  4 09:57:55 2023, max compression, original size modulo 2^32 1073741824