ossfs 2.0.8 以降ではローカルデータキャッシュがサポートされています。これは、以前に読み取ったファイルデータをローカルディスクにキャッシュし、後続の繰り返し読み取りを高速化するとともに、OSS リクエスト数を削減します。このトピックでは、ローカルデータキャッシュの動作原理、設定方法、およびパフォーマンスについて説明します。
背景情報
ossfs 2.0 を使用して OSS にアクセスする場合、ファイルを読み取るたびに毎回リモートからデータを取得する必要があります。AI トレーニングやモデルのロードなど、同一データを複数回にわたって繰り返し読み取る必要があるシナリオでは、リモートアクセスが頻繁に発生し、ネットワーク遅延と帯域幅消費が大きくなります。
ossfs 2.0 のローカルデータキャッシュは、以前に読み取ったファイルデータをローカルディスクに保持し、後続のアクセスをローカルディスクから直接提供します。これにより、繰り返し読み取りのパフォーマンスが大幅に向上し、OSS リクエストコストも削減されます。
ossfs 2.0 のローカルデータキャッシュには、次の特長があります:
-
高いパフォーマンス:大容量ファイルと小容量ファイルのいずれの繰り返し読み取りシナリオでも、帯域幅は ossfs 1.0 と比べて大幅に向上します。詳細については、以下のパフォーマンス比較をご参照ください。
-
自動エビクション:組み込みの LRU 削除ポリシーにより、キャッシュが満杯になると、最も最近アクセスされていないファイルが自動的にエビクトされ、領域が解放されます。手動でのクリーンアップは不要です。
-
大量の小さなファイルをサポート:メタデータキャッシュ (
--max_inode_cache_countおよび--attr_timeout) と併用することで、AI トレーニング用データセットの複数回ロードを大幅に高速化できます。
ローカルデータキャッシュは読み取りキャッシュにのみ使用され、書き込みパスには影響しません。書き込み操作はローカルキャッシュを経由しません。これは、読み取りデータと書き込みデータの両方をキャッシュする ossfs 1.0 の -ouse_cache とは異なります。
動作原理
キャッシュの粒度
キャッシュは OSS オブジェクト (ファイル) を基本単位として使用します。読み取り済みの各ファイルは、キャッシュディレクトリ内の 1 つのキャッシュファイルに対応し、キャッシュはオンデマンドで格納されます。
読み取りプロセス
-
初回読み取り:データは OSS から取得され、ローカルキャッシュディレクトリに同期的に書き込まれます。
-
後続の読み取り:データはローカルキャッシュから直接読み取られます。
領域解放
キャッシュが容量上限に近づくと、LRU (least recently used) ポリシーに基づいて古いファイルが自動的にエビクトされ、新しいデータのための空き領域が確保されます。領域解放は、単一のキャッシュファイルを最小単位として実行されます。
設定方法
|
設定項目 |
必須 |
説明 |
デフォルト値 |
|
disk_data_cache_dir |
いいえ |
ローカルキャッシュディレクトリのパスです。この項目を空でない値に設定すると、データキャッシュが有効になります。 |
空 |
|
disk_data_cache_size |
条件付きで必須 |
最大キャッシュ容量です。GiB 単位に調整されます。キャッシュディレクトリが存在するディスクまたはパーティションの使用可能領域を超えることはできません。disk_data_cache_dir を指定する場合、このパラメーターは有効な値に設定する必要があります。 |
空 |
|
disk_data_cache_io_engine |
いいえ |
ディスクキャッシュの IO エンジンです。有効な値: psync、libaio。 |
psync |
制約:
-
--disk_data_cache_dir が指すディレクトリは、既存の空のディレクトリである必要があります。キャッシュパスは、独立したパーティションまたは独立したディスク上に配置することを推奨します。
-
--disk_data_cache_size は、キャッシュディレクトリが存在するディスクの使用可能領域を超えることはできません。
-
同一マシン上に複数の ossfs2 インスタンスをマウントする場合、各インスタンスは独立したキャッシュディレクトリを使用する必要があります。
-
ossfs2 プロセスが終了しても、キャッシュディレクトリは自動的にクリーンアップされません。手動でクリーンアップする必要があります。
-
マウント後は、不明なエラーを防ぐために、キャッシュディレクトリのパスに対する操作を避けてください。
マウントコマンドの例:
ossfs2 mount /mnt/oss/ \
--oss_bucket <your-bucket> \
--oss_endpoint <your-endpoint> \
--oss_access_key_id <ak> \
--oss_access_key_secret <sk> \
--disk_data_cache_dir /mnt/disk/ossfs2/cache \
--disk_data_cache_size 256G
環境要件
|
パラメーター |
要件 |
|
キャッシュディスクのファイルシステム |
ext4、xfs、または tmpfs (psync モードのみ)。その他のファイルシステムは検証されていません。 |
|
キャッシュディスクの種類 |
Elastic エフェメラルディスクまたはローカル NVMe を推奨します。ESSD PL0/PL1/PL2 のスループットはボトルネックになりやすく、パフォーマンスが低下する場合があります。メモリが十分な場合は、tmpfs を使用できます (psync のみ)。 |
|
キャッシュディスクの使用可能領域 |
--disk_data_cache_size に設定した値以上 |
使用上の推奨事項
ローカルデータキャッシュは、読み取りが多く書き込みが少ない、かつ同一データへの繰り返しアクセスが必要なシナリオに適しています。
IO エンジン (disk_data_cache_io_engine) の設定に関する推奨事項:
-
psync:同期的な読み取り/書き込みシステムコールを使用します。読み取り時、データはオペレーティングシステムのページキャッシュを経由します。キャッシュされたデータ量が使用可能メモリに近い、またはそれ以下の場合、ホットデータは自然にページキャッシュに常駐し、メモリ速度に近い読み取り速度を実現できます。これは、汎用シナリオ、低スペックのクラウドディスク、および tmpfs キャッシュディスク (tmpfs は libaio をサポートしません) に適しています。
-
libaio:Linux の非同期 IO インターフェースを使用し、ページキャッシュをバイパスしてディスクを直接操作します。これは、大容量のローカル NVMe と、メモリを大幅に超えるデータセットを扱うシナリオに適しており、通常は psync と比べて約 20% のさらなる性能向上が得られます。
次の表に、代表的なシナリオと推奨設定を示します:
|
シナリオ |
使用上の推奨事項 |
|
AI トレーニングデータの複数回ロード (複数のエポックにわたって同一データセットへの繰り返しアクセス)、または固定データセットに対する複数回のクエリ/分析 |
ローカルデータキャッシュを有効にし、--disk_data_cache_size をデータセットサイズ × 1.1 に設定します。キャッシュディスクがローカル NVMe でデータ量が大きい場合は、ディスク性能を最大限に活用するために --disk_data_cache_io_engine=libaio を推奨します。 |
|
大規模モデル推論 / vLLM のロード (GB 規模のモデルファイルの繰り返しロード) |
推奨インスタンスタイプのメモリがモデル総サイズを上回る場合は、tmpfs ディスクをキャッシュディスクとして使用します。メモリが不足してモデルファイルを完全にキャッシュできない場合は、ローカルディスクをキャッシュディスクとして使用することもできますが、パフォーマンスはディスク性能に制約されます。この場合、ローカルデータキャッシュを有効にするかどうかは、事前に個別評価したうえで判断してください。 |
データの即時性が強く求められ、かつデータが頻繁に変更されるシナリオでは、データキャッシュを有効にすることは推奨しません (キャッシュされたデータとソースデータとの間に時間的な差異が生じるため)。
パフォーマンス比較
テスト対象:ossfs 2.0.9 と ossfs 1.91.10。表の「初回読み取り / 後続の読み取り」は、それぞれキャッシュミス (OSS からデータを取得する必要がある) とローカルキャッシュヒットに対応します。「—」は、キャッシュがない構成であり、初回と後続の読み取りを区別しないことを示します。
シナリオ 1:大容量ファイルのシーケンシャル読み取り (4 スレッドで 100 GB ファイルを読み取り)
テスト環境
-
マシン:ecs.i4.4xlarge (16 vCPU、 128 GiB)
-
ローカル NVMe ディスク:3576 GiB NVMe (読み取り帯域幅 6 GB/s、 書き込み帯域幅 3 GB/s、 IOPS 900,000)
-
ossfs 2.0:--disk_data_cache_dir=<path> --disk_data_cache_size=3T、--disk_data_cache_io_engine=psync と libaio の場合でそれぞれテスト
-
ossfs 1.0:-ouse_cache=<path> -oparallel_count=128
結果
|
構成 |
IO モード |
帯域幅 (初回読み取り / 後続の読み取り) |
CPU (平均/最大) |
ピークメモリ |
|
ossfs 2.0 (キャッシュなし) |
- |
2841 MB/s — |
385% / 468% |
5170 MB |
|
ossfs 2.0 |
psync |
2561 / 4516 MB/s |
371% / 526% |
2118 MB |
|
libaio |
2343 / 6625 MB/s |
298% / 322% |
2146 MB |
|
|
ossfs 1.0 |
- |
1249 / 2648 MB/s |
815% / 1214% |
137 MB |
結論:
-
キャッシュを有効にすると、大容量ファイルの後続の読み取りシナリオにおいて、ossfs 2.0 は ossfs 1.0 の約 2.5 倍 の性能を発揮します (libaio モード:6625 vs 2648 MB/s)。ローカル NVMe の性能上限に達しつつ、CPU 使用率も大幅に低下します (約 300% vs 800%)。
シナリオ 2:大量の小さなファイルの読み取り (ImageNet トレーニングデータセットのロード)
テスト環境
-
マシン:ecs.i4.32xlarge (128 vCPU、 1024 GiB)
-
ローカル NVMe ディスク:8 × 3576 GiB NVMe
-
データセット:ImageNet トレーニングセット (約 130 万枚の画像)。複数のエポックにわたって繰り返しロード
-
ossfs 2.0:--disk_data_cache_dir=<path> --disk_data_cache_size=1500G --disk_data_cache_io_engine=libaio --attr_timeout=36000 --max_inode_cache_count=11000000 (メタデータキャッシュ有効)
-
ossfs 1.0:-ouse_cache=<path> -oreaddir_optimize -omax_stat_cache_size=11000000 -ostat_cache_expire=72000
結果
|
構成 |
帯域幅 (初回読み取り / 後続の読み取り) |
CPU (平均/最大) |
ピークメモリ |
|
ossfs 2.0 (キャッシュなし) |
304 MB/s — (約 2400 img/s) |
67% / 209% |
5062 MB |
|
ossfs 2.0 |
286 / 1292 MB/s (約 10000 img/s) |
219% / 1068% |
6470 MB |
|
ossfs 1.0 |
38 / 224 MB/s (約 2000 img/s) |
66.1% / 206% |
31.6 GB |
結論:
-
ディスクキャッシュとメタデータキャッシュを有効にすると、ossfs 2.0 の後続エポックにおけるロード性能は、ディスクキャッシュなしの場合と比べて 4.25 倍 に達します (1292 vs 304 MB/s)。また、OSS へのネットワークリクエストは完全に排除されます。同一データセットを複数回にわたって繰り返しロードする AI トレーニングのワークロードでは、ossfs 2.0 のローカルデータキャッシュ + libaio を強く推奨します。