Mountpoint for Amazon S3 にメモリ使用量の制御が追加されたので、書き込み用に同時に開けるファイル数を確認してみた

Mountpoint for Amazon S3 にメモリ使用量の制御が追加されたので、書き込み用に同時に開けるファイル数を確認してみた

Mountpoint for Amazon S3 でメモリ使用量の目標値を指定できるようになりました。--memory-target の値を変えて EC2 上でマウントし、起動ログに出る「書き込み用に同時に開けるファイル数」の上限と、それを超えたときの挙動を確認しました。指定しなくても目標値は決まり、書き込み用に同時に開けるファイル数にも上限がかかります。
2026.08.30

はじめに

2026年8月26日、Mountpoint for Amazon S3 に、プロセス全体のメモリ使用量の目標値を MiB 単位で指定する --memory-target が追加されました。

https://aws.amazon.com/about-aws/whats-new/2026/08/mountpoint-for-S3-adds-memory-usage-controls

https://dev.classmethod.jp/articles/mountpoint-for-S3-adds-memory-usage-controls/

https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md

What's New では、これまでの挙動が次のように説明されています。

Previously, Mountpoint's memory usage could expand over time based on usage patterns, potentially causing performance or stability issues when competing with other memory-intensive applications.

項目 以前 今回
プロセス全体のメモリ使用量の目標値 指定できない --memory-target で MiB 単位で指定できる(最小 512 MiB)
未指定時の扱い 使用パターンによって、時間とともに増加する可能性があった 搭載メモリまたは cgroup 制限の 95% を目標値として適用(95% が 512 MiB を下回る場合は 512 MiB)
書き込み用に同時に開けるファイル数の上限 メモリ目標値に基づく上限なし 目標値と読み込み・書き込みパートサイズから決まり、起動ログに出力される(v1.24.0 で追加)
メモリ逼迫時の挙動 公式ドキュメントでは確認できず I/O を遅らせ、不要なバッファを解放し、プリフェッチを減らす

変わったのは、指定できるようになったことだけではありません。値を指定しない場合も、搭載メモリまたは cgroup 制限から決まる目標値が適用されます。cgroup 制限から目標値を決める方法も公式ドキュメントに書かれていますが、今回検証したのは搭載メモリから目標値が決まるケースです。

メモリが逼迫したときの挙動は、CHANGELOG に次のように書かれています。

This target is not a guaranteed limit but Mountpoint manages the memory available for data buffers to stay within the target: under memory pressure it slows down I/O, reclaims buffers it no longer needs and reduces prefetching.

--memory-target は v1.24.0(2026年8月24日リリース)で追加され、今回の検証も同じバージョンで行いました。書き込み用に同時に開けるファイル数の上限は、CHANGELOG では新機能ではなく Breaking changes に分類されています。--memory-target の指定の有無にかかわらず上限がかかるため、バージョンを上げた時点で挙動が変わります。

Mountpoint now limits how many files can be open for writing at the same time, derived from --memory-target and --write-part-size. Once the limit is reached, opening a file for writing fails with ENOMEM until an existing write file handle is closed.

本記事では、目標値ごとに決まる「書き込み用に同時に開けるファイル数」の上限(以下、上限数)と、上限数を超えたときの挙動を確認しました。

検証内容

確認したのは、目標値を変えてマウントし直すことと、Python で書き込み用のファイルを閉じないまま開き続けることの2つです。

検証環境

v1.24.0 では、上限数は目標値と読み込みパートサイズ・書き込みパートサイズから計算されます。検証環境では cgroup のメモリ制限が適用されていないため、未指定時の目標値は搭載メモリから決まります。

  • EC2 t3.medium(free -m の total は 3835 MiB)、Amazon Linux 2023
  • Mountpoint は RPM パッケージの 1.24.0
  • リージョンは ap-northeast-1、マウント対象は汎用バケット1個
  • --read-part-size--write-part-size の既定値はどちらも 8388608 バイト(8 MiB)

mount-s3 --help の該当部分です。

      --memory-target <MiB>
          Target for Mountpoint's total memory usage, in MiB.

          Mountpoint manages the memory used to buffer reads and writes to stay within this target but it is
          not a guaranteed limit. Lowering it may reduce throughput and increase latency.

      --read-part-size <SIZE>
          Part size for GET in bytes [default: 8388608]

      --write-part-size <SIZE>
          Part size for multi-part PUT in bytes [default: 8388608]

目標値ごとの上限数

目標値を変えてマウントし、起動ログを確認してからアンマウントする操作を4回繰り返しました。次のコマンドでマウントし、ログを取得しました。

mount-s3 amzn-s3-demo-bucket /mnt/s3 --memory-target 512
journalctl -e SYSLOG_IDENTIFIER=mount-s3 --no-pager -o cat | grep write_handle_limiter

4パターンの出力から、マウント成功行と該当ログ行のみを抜粋しました。

===== memory-target=512 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 47 (memory target 512 MiB, write part size 8 MiB)
===== memory-target=1024 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 111 (memory target 1024 MiB, write part size 8 MiB)
===== memory-target=2048 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 223 (memory target 2048 MiB, write part size 8 MiB)
===== memory-target=none =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 397 (memory target 3644 MiB, write part size 8 MiB)
--memory-target ログ上の目標値 上限数
512 512 MiB 47
1024 1024 MiB 111
2048 2048 MiB 223
未指定 3644 MiB 397

未指定時の目標値 3644 MiB は、搭載メモリ 3835 MiB の約 95% です。公式ドキュメントにある「総メモリまたは cgroup 制限の 95%」という記述と一致しました。

上限数は4パターンとも、公式ドキュメントの計算式どおりでした。式は CONFIGURATION.md の「Maximum number of files open for writing」に書かれています。

https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md

cap = (memory_target − max(128 MiB, memory_target / 8) − read_part_size) / write_part_size

目標値が 512 MiB の場合は、Mountpoint がオーバーヘッド用に 128 MiB、読み込み用に 8 MiB を確保します。書き込みに使えるのは 376 MiB で、上限は (512 − 128 − 8) / 8 = 47 ファイルでした。計算で生じた端数は切り捨てられます。

目標値を倍にしても、上限数は倍にはなりません。オーバーヘッド分と読み込み分が先に差し引かれます。さらに、目標値が 1024 MiB を超えると、オーバーヘッド分の計算が memory_target / 8 に切り替わるため、差し引かれる量が増えます(2048 MiB なら 256 MiB)。

式の分母は書き込みパートサイズなので、--write-part-size を小さくすれば上限数は増えます。ただし、マルチパートアップロードは最大 10,000 パートなので、1オブジェクトの最大サイズも小さくなります。今回は書き込みパートサイズを変えていないため、変える場合は別途確認してください。

上限を超えたオープンの失敗

目標値 512 MiB(上限 47 ファイル)でマウントし、上限を確実に超えるため、Python で書き込み用にファイルを開き、閉じないまま 60 ファイルまで増やしました。

[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 47 (memory target 512 MiB, write part size 8 MiB)
opened successfully: 47
failed at file #48: errno=12 (ENOMEM) Cannot allocate memory

起動ログに出た上限数どおり、47 個目までのオープンは成功し、48 個目のオープンが ENOMEM(Cannot allocate memory)で失敗しました。

続けて、開いたハンドルを1つ閉じてから再オープンを試しました。

opened=47, next open failed: errno=12 (ENOMEM)
after closing 1 handle, waited 0s cumulative: open failed errno=12 (ENOMEM)
after closing 1 handle, waited 1s cumulative: open SUCCESS

今回の環境では、ハンドルを閉じた直後の再オープンは失敗し、1秒後の再試行で成功しました。CHANGELOG には、既存の書き込みハンドルが閉じられるまで、書き込み用のオープンは失敗するとあります。ただし、閉じた直後に枠が空くとは限りません。

上限数に達すると、速度が落ちるのではなく open() が失敗します。同時オープン数が上限数に達する可能性があるアプリケーションでは、開くファイル数を制御するか、ENOMEM を処理する必要があります。再試行を実装する場合は、即時再試行を繰り返すのではなく、待機を入れることを検討します。

まとめ

従来、Mountpoint のメモリ使用量は時間とともに増加することがありましたが、今回のアップデートで、メモリ使用量を目標値内に収める制御が入りました。目標値を指定しなくても、搭載メモリまたは cgroup 制限から目標値が決まります。バージョンを上げるだけでも目標値は適用されます。Mountpoint を使っていてメモリ不足や OOM に困っていた場合は、バージョンアップと --memory-target の調整をお試しください。

一方で、目標値から上限数が決まり、上限数に達するとそれ以降のオープンは ENOMEM で失敗するという代償もあります。まず起動ログで自環境の上限数を確認してください。上限数は目標値を上げれば増えますが、書き込み中のファイル1つにつきパートサイズ分のバッファを確保するため、同時オープン数に応じたメモリが必要になります。インフラのメモリ増強だけで対応し続けると、EC2 や Fargate へ割り当てるメモリが増え、運用の手間や AWS 利用費も増えます。アプリケーション側の対策として、同時に開くファイル数の抑制や、書き込みを AWS SDK や AWS CLI で行う方法をご検討ください。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事