S3にダミーファイルを大量に保存

検証目的でS3にダミーファイルを大量に保存するスクリプトを書きました。

スクリプトRubyBashの組み合わせです。

Rubyでput_object

RubyAWSを操作するには aws-sdk のインストールが必要です。

$ gem install -N aws-sdk

この記事では aws-sdk のバージョンは 3.0.1 で動かしています。

RubyでS3にファイルを1つ保存するには以下のようなコードになります。 ~/.aws/config, ~/.aws/credentials にIAMユーザが登録されている前提です。

このサンプルコードで保存するファイルは5バイトで、メタデータも付与しています。

require 'aws-sdk'

profile = "default"
s3_bucket = ...
s3_key = ...

credentials = Aws::SharedCredentials.new(profile_name: profile)
s3_client = Aws::S3::Client.new(credentials: credentials)

s3_client.put_object(
  body: "Hello",
  bucket: s3_bucket,
  key: s3_key,
  metadata: {
    "aaa" => "AAA",
    "bbb" => "BBB",
  },
)

PythonでS3に保存するサンプルコードは先日の記事にあります。

RubyAWS SDKを使うサンプルコードは以下の記事にもあります。

Rubyスクリプトで3万個保存

put_object をループで回すことで大量に保存します。以下のスクリプトで3万個のファイルを保存できます。

バケット名は適切なものに変更してください。

require 'aws-sdk'

profile = "default"
s3_bucket = "sample"
s3_key_prefix = "many-s3/"

credentials = Aws::SharedCredentials.new(profile_name: profile)
s3_client = Aws::S3::Client.new(credentials: credentials)

i = ARGV[0].to_i

30.times do |j|
  10.times do |k|
    puts(sprintf("%02d/%02d/%01d", i, j, k))
    100.times do |l|
      s3_key = s3_key_prefix + sprintf("%02d/%02d/%01d/%02d.txt", i, j, k, l)
      s3_client.put_object(
        body: "",
        bucket: s3_bucket,
        key: s3_key,
        metadata: {
          "aaa" => "AAA",
          "bbb" => "BBB",
        },
      )
    end
  end
end

Bashスクリプトで36万個保存

Rubyでループを回して put_object し続けるのは時間がかかるので、上記Rubyスクリプトを並列で動かすことで高速化します。以下のBashスクリプトで12個のRubyプロセスを動かします。これで合計36万個のファイルを保存できます。

for i in $(seq 12); do
    ruby put3.rb $i &
done
wait

※並列数12が適切なのかは検証していないです。並列せず1プロセスで36万個よりは速そうです。

動かす

$ bash put36.sh

私の環境で28分ぐらいかかりました。

以下のコマンドでファイルができていることが確認できます。

$ aws s3 ls --recursive s3://sample/many-s3/ | head
2020-11-10 21:33:32          0 many-s3/01/00/0/00.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/01.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/02.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/03.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/04.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/05.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/06.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/07.txt
2020-11-10 21:33:32          0 many-s3/01/00/0/08.txt
2020-11-10 21:33:33          0 many-s3/01/00/0/09.txt

ファイル数を確認すると計算通りです。このコマンドだけで2分ぐらいかかりました。

$ aws s3 ls --recursive s3://sample/many-s3/ | wc -l
360000