こんにちは~浮田です。
2026年4月7日、AWSが Amazon S3 Files をリリースしました。
S3をフォルダみたいに使いたい、と思ったことはありませんか?Mountpointで「できる!」と思ったら制約だらけで諦めた方も多いはず。私も一回諦めました(笑)
今回、リリースされたS3 Filesで、その悩みがかなり解消されました。
Amazon S3 Files は「S3バケットをファイルシステムとしてマウントできる」という機能です。
2023年にリリースされた Mountpoint for S3 でもマウントはできていました。ただし、既存ファイルの編集もファイル名の変更もできない、読み取り特化の「なんちゃってフォルダ」でしたが。
では何が違うのか。
ドキュメントを読むだけでなく、実際に手を動かして、同じS3バケットを両方の方法でマウントして、同じ操作を試して比べてみました。
ハンズオンの前に、仕組みを理解しておくと結果の意味がわかりやすくなります。
LinuxやMacなどのOS間で「ファイル操作の命令を統一しよう」という規格です。
① 基本的なファイル操作
② ディレクトリ操作
③ パーミッション・所有者
④ 高度な操作(複数プロセスの排他制御やファイルをメモリにマッピング)
意図的な設計判断です。AWS公式ブログにはこう書かれています。
「S3のオブジェクトAPIで効率よく実装できない操作はサポートしない」
たとえば rename() を例にすると:
ローカルのrename:
ファイル名のメタデータを書き換えるだけ → 一瞬で完了
MountpointでS3のrename:
新しいキーにオブジェクトをコピー
→ 古いキーを削除
→ S3への2回のAPIコール、アトミックでない
→ 10万ファイルなら10万回×2 = 20万回のAPIコール
これを「rename()」という顔をして提供すると、「一瞬で終わるはず」という期待を裏切ることになります。だから実装しない、という判断です。
S3の上に直接実装しようとしなかったからです。
Mountpoint:S3 APIの上でPOSIXをエミュレート
→ S3の制約がそのまま制約になる
S3 Files :EFS(本物のファイルシステム)をキャッシュ層として使う
→ EFSでrenameを実行 → あとでS3に同期
→ POSIXの制約はEFSが引き受ける
EFSはもともとフルPOSIX準拠のファイルシステムなので、その上に乗っかることで自然にフルPOSIXセマンティクスが実現できています。
S3 FilesはEFSの技術を内部実装として借りてるみたいですね。
アプリが送る命令は同じ。違いはファイルシステムの実装です。
カーネルの外(ユーザー空間)でデーモンが翻訳係として動きます。
S3はファイルの部分書き込みやrenameをサポートしないため、これらの操作は実装できません。
NFSはカーネルに組み込まれたプロトコルなので、フルのファイルシステム機能が使えます。内部でEFSをキャッシュ層として使い、データの実体はS3に置きます。
S3バケット(mount-s3-demo-202604)
↓
同じバケットを2つの方法でマウント
↓
ターミナルから接続します。
# キーペアのパーミッション変更(必須。これをしないとSSH接続できない)
chmod 400 /mnt/c/Users/[ユーザー名]/Downloads/s3files-key.pem
# SSH接続(パブリックIPはEC2コンソールで確認)
ssh -i /mnt/c/Users/[ユーザー名]/Downloads/s3files-key.pem ec2-user@[パブリックIP]
ssh -i "s3files-key.pem" ec2-user@ec2-12-234-45-678.ap-northeast-1.compute.amazonaws.com
[ec2-user@ip-172-31-xx-xxx ~]$ のプロンプトが表示されれば接続成功です。
マウント用にS3バケットを作成します。
今回はmount-s3-demo-202604という名前で作成しました。
# ダウンロード&インストール
wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
sudo yum install -y ./mount-s3.rpm
# バージョン確認
mount-s3 --version
# → mount-s3 1.x.x
デフォルトではec2-userがFUSEマウントにアクセスできませんでした。
設定ファイルを変更します。
sudo nano /etc/fuse.conf
# user_allow_other の行を編集:
# 変更前
# user_allow_other
# 変更後
user_allow_other
Ctrl+X → Y → Enter で保存します。
# 確認
cat /etc/fuse.conf
# → user_allow_other の行から # が消えていればOK
# マウント先フォルダ作成(空フォルダでなければならない)
sudo mkdir /mnt/mountpoint-s3
# マウント(--allow-other と --uid 1000 が必要)
sudo mount-s3 mount-s3-demo-202604 /mnt/mountpoint-s3 --allow-other --uid 1000
# 確認
ls /mnt/mountpoint-s3
# → 空のバケットなので何も表示されなければOK
オプションの意味
# ファイル作成
echo "Mountpointのテスト" > /mnt/mountpoint-s3/mp_test.txt
# 確認
cat /mnt/mountpoint-s3/mp_test.txt
# → Mountpointのテスト
# S3への反映確認
aws s3 ls s3://mount-s3-demo-202604
# → mp_test.txt が表示される
実際にS3のコンソールを見に行くと作成されてました。
こちらは即時反映されてます。
# 既存ファイルの上書き
echo "書き換えてみる" > /mnt/mountpoint-s3/mp_test.txt
# → -bash: /mnt/mountpoint-s3/mp_test.txt: Operation not permitted ❌
# ファイル名変更
mv /mnt/mountpoint-s3/mp_test.txt /mnt/mountpoint-s3/mp_renamed.txt
# → mv: cannot move '...': Function not implemented ❌
# 追記
echo "追記してみる" >> /mnt/mountpoint-s3/mp_test.txt
# → -bash: /mnt/mountpoint-s3/mp_test.txt: Operation not permitted ❌
3つとも失敗しました。 エラーコードの意味は以下のとおりです。
|
エラーコード |
意味 |
|
EPERM(Operation not permitted) |
その操作自体をサポートしていない。権限の問題ではない |
|
ENOSYS(Function not implemented) |
そのシステムコール自体が未実装 |
EPERM は「権限がない」ではなく「その操作はそもそもできない」という意味です。
Mountpointが意図的に既存ファイルの上書きをサポートしていないため返ってきます。
ENOSYS はMountpointが rename() システムコールを実装していないため返ってきます。
AWSコンソール → S3 → 左メニュー「ファイルシステム」→「ファイルシステムの作成」
押下するとこのような画面が開きます。
S3ファイルの開始方法が載っているので、基本的にはかいてる通りに進めていけば良さそうですね。
バケット名に先ほど作成したバケット名( mount-s3-demo-202604 )を入力して作成します。
⚠️バージョニングが必須です
S3 Filesを使うにはS3バケットのバージョニングが有効化されている必要があります。
コンソールからファイルシステムを作成すると自動で有効化されますが、既存バケットに後から適用する場合は旧バージョンが保持されることによるストレージコスト増と、既存のライフサイクルルールとの整合性を事前に確認してください。
作成後、ファイルシステムIDが発行されます。
fs-011a011a1234f12345
マウントターゲットが自動作成されます。
画面上部に画像のような表示がされます。
「利用可能」になるまで2〜3分待つ必要があるそうです。私も3分ほど待ちました。
S3 FilesはNFSプロトコル(TCP 2049番)を使います。
EC2のセキュリティグループにインバウンドルールを追加します。
EC2ダッシュボード → インスタンス選択 → セキュリティタブ → セキュリティグループ → インバウンドルールを編集
|
タイプ |
プロトコル |
ポート |
ソース |
|
NFS |
TCP |
2049 |
0.0.0.0/0 |
本番環境では 0.0.0.0/0 は使わないでください
0.0.0.0/0 はすべてのIPアドレスからのアクセスを許可する設定です。今回はハンズオン用に簡略化しています。
S3 FilesはEFSのドライバーを使います。
# インストール
sudo yum install -y amazon-efs-utils
# バージョン確認(コマンド名に注意)
mount.efs --version
# → /usr/sbin/mount.efs Version: 3.0.0
# マウント先フォルダ作成
sudo mkdir /mnt/s3files
# マウント実行
sudo mount -t s3files fs-011a011a1234f12345 /mnt/s3files
# マウント確認
mount | grep s3files
# → 127.0.0.1:/ on /mnt/s3files type nfs4 (rw,vers=4.2,...)
書き込みでPermission deniedが出る場合はこれを実行 してみてください
デフォルトではファイルの所有者が root になっているためec2-userに変更します。
# 所有者確認 ls -la /mnt/s3files
→ root root になっている
# 所有者変更
sudo chown ec2-user:ec2-user /mnt/s3files
sudo chown ec2-user:ec2-user /mnt/s3files/mp_test.txt
# 確認 ls -la /mnt/s3files
→ ec2-user ec2-user になっていればOK
# ファイル確認(Mountpointで作ったファイルが見える)
ls /mnt/s3files
# → mp_test.txt
同じS3バケットをマウントしているので、Mountpointで作ったファイルがS3 Files側からも見えます。
# 1. 既存ファイルの上書き
echo "書き換えてみる" > /mnt/s3files/mp_test.txt
cat /mnt/s3files/mp_test.txt
# → 書き換えてみる ✅ 成功!
# 2. ファイル名変更(mv)
mv /mnt/s3files/mp_test.txt /mnt/s3files/sf_renamed.txt
ls /mnt/s3files
# → sf_renamed.txt ✅ 成功!
# 3. 追記
echo "追記してみる" >> /mnt/s3files/sf_renamed.txt
cat /mnt/s3files/sf_renamed.txt
# → 書き換えてみる
# → 追記してみる ✅ 成功!
3つとも成功しました。
S3コンソールを見に行くときちんと反映されてます
aws s3 ls s3://mount-s3-demo-202604
# → sf_renamed.txt が表示される事を確認します。
以下は実際のログなんですが、リネームした際に反映に時間がかかっていることが確認できました。
$ echo "書き換えてみる" > /mnt/s3files/mp_test.txt
$ cat /mnt/s3files/mp_test.txt
書き換えてみる
$ mv /mnt/s3files/mp_test.txt /mnt/s3files/sf_renamed.txt
$ echo "追記してみる" >> /mnt/s3files/sf_renamed.txt
$ ls /mnt/s3files
sf_renamed.txt
$ cat /mnts3files/sf_renamed.txt
書き換えてみる
追記してみる
$ aws s3 ls s3://mount-s3-demo-202604
PRE /
2026-04-09 04:44:31 23 mp_test.txt ←まだ反映がされていない
$ aws s3 ls s3://mount-s3-demo-202604
PRE /
2026-04-09 04:46:26 41 sf_renamed.txt ←反映がされた!
反映に時間がかかるのは意図的な設計です。
60秒という数字を「遅い」と感じるかもしれませんが、これは単なる制約ではなくコスト最適化の仕組みでもあります。
ログファイルへの追記のように短時間に何度も書き込みが発生するケースでは、60秒のウィンドウ内での変更が集約され、S3へは1回のPUTとして反映されます。書き込みのたびにS3のバージョンが作られるのではなく、まとめて一つのオブジェクトになるため、S3のリクエストコストとバージョニングによるストレージコストが抑えられます。
ただし、ジョブAがファイルを書き込み、ジョブBがS3 API経由で即座にそのオブジェクトを取得するような構成では、最大60秒古いデータを見る可能性があります。ジョブ間の受け渡しもファイルシステム経由で行うか、S3のイベント通知で後続を起動する設計にする必要があります。
S3 Filesの設計背景を書いたAWS VP Andy Warfieldのブログが非常に興味深いので紹介します。
開発当初、チームは「EFS3」という名前でファイルとオブジェクトを完全に統合することを目指していました。
しかし何ヶ月も議論を重ねた結果、どんな設計にしてもファイルかオブジェクトのどちらかが何かを犠牲にする
「不快な妥協の連続」にしかならないという結論に至り、一度行き詰まりました。
クリスマス休暇後、チームは方針を転換します。
「境界を消す」のではなく、「境界そのものを設計の核心にする」という逆転の発想です。
そこから生まれたのが stage & commit という考え方です。gitから借りた言葉で:
ファイルとオブジェクトの境界を明示することで、どちらの特性も犠牲にせず共存できるようになりました。
「境界を消そうとして失敗し、境界を設計の核心にした瞬間にすべてがうまくいった」というのは、設計の教訓としても面白いエピソードです。
mv 自体は動きます。ただし大量のファイルが入ったディレクトリをまるごとリネームするときは注意が必要です。
S3にはrenameという操作がそもそも存在しないため、内部では「新しいキーにコピーして、古いキーを削除する」という処理に変換されます。ファイルシステム上ではrenameは一瞬で終わりますが、S3への反映はその後にバックグラウンドで走ります。
大量のファイルを含むディレクトリをrenameする場合、S3側の反映に数分かかることがあり、その間S3 APIからは古いキーしか見えない状態が続きます。日常的なファイル操作では気にする必要はありませんが、デプロイスクリプトなどで大規模なディレクトリ移動を行う場合は注意してください。
|
操作 |
Mountpoint |
S3 Files |
|
ファイル作成 |
✅ |
✅ |
|
ファイル読み取り |
✅ |
✅ |
|
既存ファイルの上書き |
❌ EPERM |
✅ |
|
ファイル名変更(mv) |
❌ ENOSYS |
✅ |
|
追記(>>) |
❌ EPERM |
✅ |
|
S3への自動同期 |
✅(即時) |
✅(遅延あり) |
|
項目 |
Mountpoint |
S3 Files |
|
リリース |
2023年8月 |
2026年4月 |
|
プロトコル |
FUSE(ユーザー空間) |
NFS v4.2(カーネル内) |
|
レイテンシ |
S3と同等 |
アクティブデータ約1ms |
|
同時接続 |
各自独立 |
最大25,000接続 |
|
ファイルロック |
❌ |
✅ |
|
追加コスト |
なし |
あり |
|
Linux専用 |
✅ |
✅ |
|
指標 |
値 |
|
1クライアントあたり最大リードスループット |
3 GiB/s |
|
ファイルシステムあたり合計リードスループット |
テラバイト/秒級 |
|
ファイルシステムあたり最大リードIOPS |
250,000 |
|
ファイルシステムあたり最大ライトIOPS |
50,000 |
|
S3→FSの反映速度 |
最大2,400オブジェクト/秒 |
|
FS→S3のコミット間隔 |
約60秒 |
EBSのgp3ボリュームのデフォルトスループットが125MiB/sであるのに対し、S3 Filesは1クライアントあたり3GiB/sを出せます。しかもボリュームのプロビジョニング不要で使った分だけの課金です。
「既存ファイルを書き換えたい」
または「複数インスタンスが同時に書き込みたい」
または「mvやflockを使いたい」
↓ Yesが1つでもある
→ S3 Files
上記すべてがNo(読み取り+新規書き込みのみ)
→ Mountpoint(無料・シンプル)
実際に試してぶつかったエラーと対処法です。同じ環境(WSL → EC2)で試す方の参考になれば。
|
エラー |
原因 |
対処法 |
|
Failed to create FUSE session |
sudoなしで実行 |
sudo mount-s3 で実行 |
|
Permission denied(ls時) |
--allow-other なし |
オプションを追加して再マウント |
|
sed -i で /etc/fuse.conf が変わらない |
#user_allow_other の前にスペースがある |
sudo nano /etc/fuse.conf で直接編集 |
|
Permission denied(書き込み時1) |
user_allow_other が無効 |
/etc/fuse.conf を編集して user_allow_other を有効化 |
|
Permission denied(書き込み時2) |
--uid 未指定 |
--uid 1000 を追加(ec2-userのuidに合わせる) |
|
mount point does not exist |
マウント先フォルダ未作成 |
sudo mkdir /mnt/s3files |
|
timeout(S3 Files) |
マウントターゲットのSGにNFS未設定 |
TCP 2049を追加 |
|
Permission denied(S3 Files書き込み時) |
ファイル所有者が root |
sudo chown ec2-user:ec2-user |
--allow-other は「マウントしたユーザー以外もアクセスできる」というオプションですが、これだけではファイルの所有者がrootのままです。--uid 1000 を追加することで「ファイルのオーナーをec2-user(uid=1000)として扱う」ようになり、書き込みができるようになります。
# NG:--allow-other だけだと書き込みでPermission denied
sudo mount-s3 my-bucket /mnt/mountpoint-s3 --allow-other
# OK:--uid も必要
sudo mount-s3 my-bucket /mnt/mountpoint-s3 --allow-other --uid 1000
自分のuidは id コマンドで確認できます。
EC2は起動している間課金されます。忘れずに削除してください。
# S3バケットの中身を削除
aws s3 rm s3://mount-s3-demo-202604 --recursive
# アンマウント
sudo umount /mnt/s3files
sudo umount /mnt/mountpoint-s3
# EC2からログアウト
exit
AWSコンソールで:
同じS3バケットに対して同じPOSIX命令を送っているのに、MountpointとS3 Filesで結果が全然違う。
その理由はファイルシステムの実装の違いにあります。
「読んで新規書き出しだけ」ならMountpointで十分。
「編集・共有・同時書き込み」が必要ならS3 Filesという使い分けが基本です。
冒頭で「Mountpointで諦めた」と書きましたが、S3 Filesを触ってみてその理由がよくわかりました。Mountpointは制約が多いのではなく、S3の制約をそのまま正直に見せていただけだったんですね。S3 Filesはその制約をEFSで引き受けることで解決した、という設計の話が個人的には一番面白かったです。