S3へのバックアップを aws s3 sync から aws s3 ls + aws s3 cp に切り替えて高速化した

created: 2025-06-11

まとめ

  • aws s3 sync で大量のファイルをバックアップすると、メタ情報の比較が非常に遅くなる
  • aws s3 ls --recursive でファイル一覧を取得して、ローカルの ls -lR と比較して、差分のみを aws s3 cp でアップロードする
  • 処理にかかる時間が40分から5分に短縮された

経緯

定期的にAmazon S3にファイルをバックアップしている。ファイル数はおおよそ5万~10万件、ファイルの平均サイズは数MB程度だ。 差分のみで充分なため、変更・新規追加のファイルだけをアップロードしている。そのため、以下のコマンドでバックアップしていた。

aws s3 sync --size-only local_dir/ s3://BUCKET/

しかし、この aws s3 sync による同期処理に数十分かかっていた。特に、アップロード処理自体ではなく、アップロードの開始までに時間がかかる。 80,000ファイルの状態で、ファイルのメタ情報の取得に40分ほど時間がかかっていた。 原因は、アップロードの要否を判定するために、1ファイルずつS3上のメタデータを取得して比較しているからだ。

一方、 aws s3 ls --recursive s3://BUCKET/ によってメタデータ(ファイルサイズと更新日時)を一括で取得できる。 おそらく、 S3 ListObjects API を使っていて1000件単位で情報を取得している。1ファイルごとに取得するよりは圧倒的に速くなった。

そこで、以下のような処理に変更した。

  1. aws s3 ls --recursive コマンドで、S3上のファイル情報を一括取得する
  2. ローカルでも ls -lRfind によってファイル情報を取得する
  3. 両者を比較して、S3に存在しないファイルとサイズが異なるファイルを aws s3 cp でアップロードする

この結果、バックアップにかかる時間を大幅に短縮できた。