![]() |
どうも。8月の夏休みがエンドレスにループしてほしい寺内です。
さて、Amazon S3はオブジェクトストレージです。ファイル操作やディレクトリの概念はブロックストレージにおけるそれとだいぶ違います。 ですが、S3の中のファイルをあたかもファイルシステムの一部のように操作したい、と思うことは稀にあります。またアプリケーションデータをS3に置きたいのだが、アプリケーションコードのファイルアクセス部分をS3用に作り変えることができない、という場合もあるでしょう。
そのようなときに便利なのが、Mountpoint for Amazon S3 です。 これはS3の機能のひとつとして提供されていますが、実体はLinuxにインストールするファイルアクセスクライアントソフトウェアです。オープンソースであり、GitHubで公開されています。この機能自体に料金は発生せず、通常のS3利用料金のみで利用可能です。
Mountpoint for Amazon S3 は、2023年3月にベータリリースされその後、2023年8月には一般提供開始となり本番環境で利用できるレベルになりました。そして2025年5月には fstab に対応し、OS起動時の自動マウントが可能となりました。
わたしの周囲では意外と知られていないこの便利機能を紹介していきたいと思います。
概略
Linuxのファイルシステムが持つマウント機能を利用し、S3バケットもしくはそれ以下のプレフィクス(ディレクトリ)以下を、ファイルシステムに接続(マウント)します。マウントしたとろに対して、OS内から通常のファイル操作が可能となり、そのファイル操作は即座にS3オブジェクトに反映されます。 これはEC2からでもオンプレミスからでも、S3のAPIにアクセス可能なら利用可能です。
以下は、ドキュメントに沿った説明をしていきます。
インストール
Amazon Linux 2023 のEC2からは、以下の dnf コマンドでインストールします。 ubuntuなどのDebian系Linuxでも使えますが、パッケージは異なります。
$ sudo dnf install <https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm>
手動でマウント
手動でマウントするには、 mount-s3
コマンドを使用します。
基本のマウント
ホームディレクトリ以下にマウントポイント( ~/mnt
) を作成し、そこにS3バケット( ytera-mountpoint01
)をマウントするには以下のようなコマンドとなります。
実行例: バケット名が ytera-mountpoint01
で、ホームディレクトリにある mnt
の下にマウントします。
$ cd ~
$ mkdir mnt
$ mount-s3 ytera-moutpoint01 ~/mnt
bucket ytera-moutpoint01 is mounted at /home/ec2-user/mnt
マウントを外すには、通常のアンマウントコマンドを使用します。
$ umount ~/mnt
削除権限を与えるマウント
上記の基本的なマウントでは、S3オブジェクトを読んだり追加することができますが、削除やファイルの書き換えは禁止された状態でマウントされます。
S3オブジェクトの削除を許可する場合は、以下のようにオプションを付けます。
$ mount-s3 --allow-delete ytera-mountpoint01 ./mnt
S3オブジェクトを更新することを許可するには、同じ用に --allow-overwrite
オプションを付与します。
バケットの特定プリフィクスでのマウント
バケット全体をマウントするのではなく、S3バケット内の特定のディレクトリ(プリフィクス)をマウントするには以下のように --prefix
オプションを使います。最後のスラッシュ (/
) は必須です。
mount-s3 ytera-mountpoint01 ./mnt/mount-a --prefix mount-a/
fstab での自動マウント
OSが起動した時に自動的にsystemdで自動的にマウントするには、 /etc/fstab
ファイルに定義します。fstab のオプションの詳細は省略します。 fstabでS3マウントするには、行頭からS3 URIとマウントポイントとなるディレクトリを指定します。マウントポイントとなるディレクトリは、予め作成しておいてください。
s3://ytera-mountpoint01/mount-a/ /mnt/mount-a mount-s3 _netdev,nosuid,nodev,nofail,rw 0 0
s3://ytera-mountpoint01/mount-b/ /mnt/mount-b mount-s3 _netdev,nosuid,nodev,nofail,rw 0 0
なお、末尾の 0 0
は、dumpの対象にするか否か(0は対象にしない)と、ファイルシステムチェック(fsck)の順序(0はチェックしない)という意味です。
性能は
Mountpoint for Amazon S3 の仕組み
Mountpoint for Amazon S3 は、S3にアクセスするソフトウェアです。アプリケーションレイヤからのマウントポイントへのファイルシステムコールを仮想ファイルシステムが受け取ると、S3マウント領域であればS3への呼び出し(GETやPUT)に変換します。その後、 ~/.aws/credentials
の認証情報を使用してS3 APIエンドポイントへリクエストを投げます。 そのため、性能的にはAWS CLIを使う場合とたいして変わらないはずです。いちおうやってみましょう。
実験データの準備
転送速度の実験は、以下2つのランダムデータを用意します。
- 100KBのファイルを1000個 (合計10MBほど)
- 1GBのファイルを5個 (合計5GBほど)
以下のように作ります。
mkdir -p file1000-100kb && cd file1000-100kb && for i in {1..1000}; do dd if=/dev/urandom bs=1024 count=100 2>/dev/null > file_${i}.txt; done;
mkdir -p file5-1GB && cd file5-1GB && for i in {1..5}; do dd if=/dev/urandom bs=1M count=1024 2>/dev/null > file_${i}.txt; done;
これで、ローカルディスクに file1000-100kb
と file5-1GB
というディレクトリができました。
測定方法
S3マウントしたディレクトリに、 cp -r
コマンドでコピーし、その実行時間を測定します。
$ date +"%H:%M:%S";cp -r ./file1000-100kb ./mnt/mount-a;date +"%H:%M:%S"
08:01:49
08:07:58
$ date +"%H:%M:%S";cp -r ./file5-1GB ./mnt/mount-a;date +"%H:%M:%S"
07:59:54
08:00:35
測定結果
転送データ | 転送時間 | 転送速度(計算値) |
---|---|---|
100KB x 1000 | 6分9秒(369秒) | 2.07 Mbps |
1GB x 5 | 41秒 | 930.41 Mbps |
やはり多くのリクエストを出すのは転送効率悪いですね。 これでもmount-s3 コマンドは、ある程度の並列化を行っているようです。
なお、今回の実験はNATゲートウェイ経由のインターネット接続でS3 APIエンドポイントを使っています。VPCエンドポイントを作り同じ実験をしてみましたが、ほぼ同じ結果でした。
感想
S3の中の特定パターンのファイルを大量に消すなど、細かなファイル指定をしたり、複雑なファイル移動をしたりするとき、AWS CLIでは指定が(慣れていないため)面倒です。そういうときに、Linuxコマンドでできるととても簡単にできます。
これほど便利な機能ですが、Windowsには対応していないのが残念です。WSLでubuntuを動かし、ubuntu上のマウントポイントを母艦のWindowsからアクセスすることで、似たようなことができると思います。誰かやってみてほしいです。