Object Storage Service (OSS) 永続ボリュームの読み書きパフォーマンス (レイテンシーやスループットなど) が期待どおりでない場合は、このトピックのトラブルシューティング手順と最適化プラクティスを使用して、問題を体系的に特定し、解決できます。
OSS 永続ボリュームは、シーケンシャルな読み書き操作を伴い、高帯域幅を必要とするシナリオに最適です。高い同時実行性のあるランダム書き込みを必要とするシナリオや、ファイルシステムのオーナーやモードなどの拡張ファイル属性に大きく依存するシナリオでは、NAS や CPFS などの他の永続ボリュームタイプの使用を検討してください。詳細については、「サポートされている永続ボリュームの概要」をご参照ください。
クライアントの実装原理
OSS のフラットな構造は、ファイルシステムのツリー構造とは根本的に異なります。コンテナー内のアプリケーションが read、write、stat などの標準ファイルシステムインターフェイス (POSIX ベースの API) を介して OSS にアクセスできるようにするために、CSI プラグインはアプリケーションノードでクライアントを実行します。このクライアントは ossfs 1.0、ossfs 2.0、および strmvol をサポートしています。クライアントは双方向のトランスレーターとして機能します。アプリケーションからの write などのファイル操作を、PUT Object などの OSS オブジェクトへの HTTP リクエストに変換します。次に、OSS の応答をファイルシステムの応答に変換し直します。このプロセスはファイルシステムをシミュレートします。
この変換プロセスには、ネットワーク伝送とプロトコルオーバーヘッドが伴います。したがって、OSS 永続ボリュームのパフォーマンスは、クライアントタイプ、ネットワーク条件、ノードリソース、およびアプリケーションのデータアクセスモードに密接に関連しています。
トラブルシューティングガイド
パフォーマンスの問題をトラブルシューティングする際は、次の手順に従ってください:
このトピックでは、CSI を使用して POSIX ベースの API を介して OSS にアクセスする際のパフォーマンス問題のトラブルシューティングに焦点を当てています。アプリケーションコードが OSS ソフトウェア開発キット (SDK) を直接使用している場合は、最適化のガイダンスについて「OSS パフォーマンスのベストプラクティス」をご参照ください。
クライアントが期待どおりであることを確認する: 選択したクライアントとそのパフォーマンスベースラインがシナリオに適していることを確認します。
設定エラーまたは外部ボトルネックを確認する: これらの問題は通常、アプリケーションロジックとは無関係であり、基本的な設定と環境のヘルスチェックの一部です。運用保守 (O&M) エンジニアがこのチェックを実行できます。
アプリケーションの読み書きロジックとクライアントパラメーターを最適化する: このステップでは、アプリケーションのデータアクセスモードを深く理解する必要があります。開発者はコードまたは設定を調整する必要があります。
開始する前に、クラスターの CSI コンポーネントのバージョンが v1.33.1 以降であることを確認してください。コンポーネントをアップグレードするには、「CSI コンポーネントの管理」をご参照ください。
クライアントが期待どおりであることを確認する
クライアントの選択
ossfs 1.0 と比較して、ossfs 2.0 および strmvol 永続ボリュームは、シーケンシャルな読み書き操作と小さいファイルの高い同時実行性のある読み取りにおいて、大幅なパフォーマンス向上を実現します。アプリケーションがランダム書き込みを実行しない場合は、ossfs 2.0 を使用することをお勧めします。
アプリケーションがランダム書き込みを実行するかどうかが不明な場合は、テスト環境で ossfs 2.0 永続ボリュームをマウントしてみてください。アプリケーションがランダム書き込み操作を実行すると、EINVAL エラーが返されます。
ossfs 2.0 クライアントを使用する際にパフォーマンスを最大化するために、chmodおよびchown操作はエラーを報告しませんが、効果はありません。マウントポイント配下のファイルまたはフォルダに権限を設定するには、永続ボリューム (PV) のotherOptsフィールドにマウントパラメーターを追加できます。chmodの場合は-o file_mode=<permission_code>または-o dir_mode=<permission_code>を使用します。chownの場合は-o gid=または-o uid=を使用します。
詳細な選択の推奨事項については、「クライアント選択のリファレンス」をご参照ください。
パフォーマンスの期待値
ネットワークファイルシステムとして、OSS 永続ボリュームのパフォーマンスはネットワーク層とプロトコル層の影響を受けます。パフォーマンスの問題は通常、ローカルファイルシステムと比較した場合のパフォーマンスの違いではなく、提供されているベンチマーク結果からの大幅な逸脱を示します。さまざまなクライアントのパフォーマンスベースラインは次のとおりです。
設定エラーまたは外部ボトルネックの確認
PV にインターネットエンドポイントが設定されている
クラスターと OSS バケットが同じリージョンにある場合、内部エンドポイントを使用するとネットワーク遅延を大幅に削減できます。
トラブルシューティング方法: 次のコマンドを実行して、PV に設定されている OSS エンドポイントを確認できます。
kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.url}'ソリューション: 出力が
http://oss-<region-id>.aliyuncs.comなどのインターネットエンドポイントである場合は、PV を再作成し、http://oss-<region-id>-internal.aliyuncs.comなどの内部エンドポイントを使用する必要があります。
OSS サーバーでのスロットリング
OSS には、単一のバケットに対する合計帯域幅とクエリ/秒 (QPS) に関する制限があります。一部のリージョンのサービスや、ワークフローなどの OSS への高い同時実行性のあるアクセスを伴うシナリオでは、帯域幅と QPS のスロットリングが発生する可能性があります。
トラブルシューティング方法: OSS コンソールで、OSS バケットのモニタリングメトリックを表示して、帯域幅使用量やリクエスト数などのメトリックが制限に近づいているか、または超えていないかを確認できます。
ソリューション:
リージョンの変更: 単一の OSS バケットの帯域幅と QPS の制限はリージョンによって異なります。アプリケーションがまだテスト段階にある場合は、別のリージョンに移動することを検討できます。
帯域幅のボトルネック:
データを繰り返し読み取る必要がない場合: Pod にディスクを動的にアタッチして一時的にストレージすることができます。一時データには、エラスティックエフェメラルディスク (EED) を使用できます。詳細については、「動的プロビジョニングされたボリュームの使用」をご参照ください。さまざまなディスクタイプのパフォーマンスメトリックについては、「Elastic Block Storage のパフォーマンス」をご参照ください。
レプリカまたはアプリケーションバッチ間でデータが繰り返し読み取られる場合: Fluid with JindoFS などの分散キャッシュを使用して、OSS からクラスターのキャッシュシステムにデータをプリフェッチできます。これにより、OSS への繰り返しデータリクエストを回避できます。詳細については、「JindoFS を使用した OSS ファイルへのアクセスの高速化」をご参照ください。
QPS (または IOPS) のボトルネック: ほとんどのアプリケーションでは、高い同時実行性により、QPS 制限に達する前に帯域幅制限に達します。QPS ボトルネックのみがトリガーされる場合、原因は
lsやstatなどの頻繁なメタデータ取得、または頻繁なファイルの開閉である可能性があります。この場合、クライアントの設定とアプリケーションの読み書きメソッドを確認する必要があります。最適化情報については、「アプリケーションの読み書きロジックとクライアントパラメーターの最適化」をご参照ください。
アプリケーションノードの内部帯域幅がボトルネックに達している
クライアントとアプリケーション Pod は同じノードで実行され、そのネットワークリソースを共有します。サーバーレスコンピューティング能力のシナリオでは、単一の ACS インスタンスのリソースを共有します。したがって、ノードのネットワーク帯域幅制限は、OSS 永続ボリュームの最大パフォーマンスを制約します。
トラブルシューティング方法: ノードのモニタリング情報またはECS インスタンスのモニタリング情報を表示して、帯域幅のボトルネックを確認できます。
ソリューション:
利用可能なネットワーク帯域幅が高いノードにアプリケーション Pod を優先的にスケジュールします。
ノード設定をスペックアップまたはスペックダウンして、より多くの帯域幅を取得できます。
これらのソリューションが実現不可能で、タスクが I/O 集中型である場合は、ディスクベースの永続ボリュームへの切り替えを検討できます。
ossfs 1.0 永続ボリュームのデータキャッシングが最大ディスクスループットによって制限されている
完全な POSIX 書き込み操作をサポートし、単一クライアントのデータ整合性を確保するために、ossfs 1.0 クライアントはファイルにアクセスする際にデフォルトで一部のデータをディスクにキャッシュします。このキャッシング操作は、ossfs Pod の /tmp ディレクトリで行われます。このスペースは、コンテナーランタイムデータに使用されるノード上のディスクに対応します。したがって、ossfs 1.0 のパフォーマンスは、このディスクの IOPS (input/output operations per second) とスループットの上限によって直接制限されます。
トラブルシューティング方法:
以下の方法は ContainerOS ノードには適用されません。
次のコマンドを実行して、アプリケーション Pod が実行されているノード上のコンテナーランタイムデータディスクの ID を見つけます。
kubectl get node <node-name> -o yaml | grep alibabacloud.com/data-disk-serial-id出力の
data-disk-serial-idに基づいて、一時スペースはディスクインスタンスd-uf69tilfftjoa3qb****にあります。alibabacloud.com/data-disk-serial-id: uf69tilfftjoa3qb****出力の ID が空の場合は、ECS コンソール - Elastic Block Storage - ディスクに移動します。アタッチされたインスタンスに基づいてディスクを特定し、そのモニタリング情報をクエリします。
インスタンス ID に基づいて、ディスクのモニタリング情報を表示して、ディスクに IOPS またはスループットのボトルネックがあるかどうかを判断できます。
ソリューション:
読み取り専用またはシーケンシャル書き込みシナリオの場合: ossfs 1.0 クライアントは、開いているファイルがランダムに書き込まれるかどうかを予測できません。したがって、読み取り専用操作でもディスクへのデータキャッシングがトリガーされる可能性があります。これらのアプリケーションを ossfs 2.0 などのより適切なクライアントに切り替えるか、アプリケーションに読み書き分離を実装することをお勧めします。
ランダム書き込みシナリオの場合: ossfs 1.0 などの Filesystem in Userspace (FUSE) クライアントを介したランダム書き込みのパフォーマンスは通常、低くなります。アプリケーションを変更して OSS SDK を介して OSS に直接アクセスするか、このシナリオにより適したNAS 永続ボリュームに切り替えることをお勧めします。
ossfs 1.0 永続ボリュームの一時データを格納するディスクの使用率が高い
ディスクモニタリングで ossfs 1.0 のデータキャッシング用ディスクの使用率が一貫して高い場合、特にサーバーレスコンピューティング能力のシナリオでは、一時データの頻繁なエビクションとローテーションにより、アクセスパフォーマンスがさらに低下する可能性があります。
トラブルシューティング方法:
ossfs 1.0 永続ボリュームのデータキャッシングが最大ディスクスループットによって制限されているのソリューションに従って、コンテナーランタイムデータに使用されるディスクを特定します。
ディスクモニタリングを通じてディスクのリソース使用量を確認できます。使用率が安定して高いレベルにあるが、アプリケーション自体がディスクに書き込むデータ量が少ない場合、パフォーマンスの問題は ossfs 1.0 クライアントによる一時データのローテーションが原因である可能性があります。
ソリューション:
アプリケーションロジックの確認: アプリケーションコードがファイル記述子を長時間保持している (つまり、ファイルを長時間開いたままにしている) かどうかを確認します。ファイル記述子が保持されている間、関連する一時データを解放できません。これにより、大量のローカルディスク領域が消費される可能性があります。
ローカルディスクのスケールアウト: アプリケーションロジックが正しく、現在のディスクの最大スループットが要件を満たしている場合は、ディスク容量を増やすことを検討できます。
認証 TTL が短いため、多くの RAM リクエストが発生する
認証に Resource Access Management (RAM) ロールを使用する場合、ossfs クライアント (バージョン 1.0 および 2.0) はトークンを取得し、OSS への最初のアクセス時にその有効期限を記録します。セッションの継続性を確保するために、クライアントは現在のトークンが期限切れになる 20 分前に新しいトークンを取得し、有効期限を更新します。
したがって、RAM ロールの最大セッション期間 (max_session_duration) は 20 分より長くする必要があります。
たとえば、セッション期間が 30 分の場合、クライアントは 10 分間の使用後 (30 - 20 = 10) にトークンを更新しますが、これは通常のスループットには影響しません。セッション期間が 20 分未満の場合、クライアントはトークンが常に期限切れに近いと見なします。その後、OSS へのすべてのリクエストの前に新しいトークンを取得しようとします。これにより、多くの RAM リクエストがトリガーされ、パフォーマンスに影響します。
トラブルシューティング方法: デフォルトのクライアントログレベルでは、頻繁なトークン更新動作が記録されない場合があります。アプリケーションで使用されている RAM ロールが正しく設定されていることを確認する必要があります。
ソリューション: 「RAM ロールの最大セッション期間の設定」をご参照ください。RAM ロールの最大セッション期間をクエリして変更します。設定が正しいことを確認してください。
アプリケーションの読み書きロジックとクライアントパラメーターの最適化
メタデータキャッシングの最適化 (および無効化の回避)
メタデータキャッシングは、ls や stat などの高頻度操作のパフォーマンスを向上させるためのコアメカニズムです。時間のかかるネットワークリクエストを大幅に削減できます。無効にしたり、誤って設定したりすると、クライアントはデータ整合性を確保するために OSS から頻繁にデータをリクエストする可能性があり、パフォーマンスのボトルネックになります。
トラブルシューティング方法:
次のコマンドを実行して、PV に設定されているクライアントパラメーターにキャッシュを無効にするオプションが含まれているかどうかを確認できます。kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.otherOpts}'ソリューション:
キャッシュの無効化を回避する: コマンドの出力に
max_stat_cache_size=0(ossfs 1.0 の場合) またはclose_to_open=true(ossfs 2.0 の場合) が含まれており、シナリオで強力な整合性が必要ない場合は、永続ボリュームを再作成してこれらのパラメーターを削除する必要があります。キャッシュ設定の最適化: アプリケーションが読み取るデータが頻繁に更新されない場合は、メタデータキャッシュのサイズと有効期限を増やすことで、パフォーマンスをさらに向上させることができます。
ossfs 1.0 永続ボリューム: 「メタデータキャッシュ」をご参照ください。
ossfs 2.0 永続ボリューム: 「OSS リクエストを削減し、マウントポイントのパフォーマンスを向上させる」をご参照ください。
strmvol 永続ボリューム: デフォルトでは、マウントポイント配下のすべてのメタデータはキャッシュされ、有効期限はありません。通常、追加の設定は必要ありません。
拡張オブジェクト情報の維持を回避する (ossfs 1.0 のみ)
mode、gid、uid などのファイルシステムメタデータは、OSS のオブジェクトの拡張情報と見なされます。ossfs 1.0 クライアントは、この情報を取得するために追加の HTTP リクエストを行う必要があります。クライアントはデータアクセスパフォーマンスを向上させるためにこのメタデータ (基本プロパティと拡張プロパティを含む) をデフォルトでキャッシュしますが、特に拡張プロパティの頻繁なメタデータ取得は、パフォーマンスのボトルネックのままです。
したがって、これらのシナリオのパフォーマンス最適化は、次の 2 つの点に焦点を当てています:
メタデータ取得操作の数を最小限に抑えます。詳細については、「メタデータキャッシングの最適化 (および無効化の回避)」をご参照ください。
各取得の時間コストを削減するために、オーバーヘッドの高い拡張プロパティのリクエストを回避します。
ソリューション:
アプリケーションがファイルシステムメタデータに依存しない場合:
readdir_optimizeパラメーターを設定して、拡張情報の維持を無効にすることをお勧めします。chmod、chown、stat、およびその他の操作の動作は、ossfs 2.0 と同じになります。アプリケーションがグローバルな権限設定のみを必要とする場合: ルート以外のコンテナーに権限が必要なシナリオでは、
readdir_optimizeパラメーターを設定することをお勧めします。同時に、gid、uid、およびfile_mode/dir_modeパラメーターを使用して、ファイルシステムのデフォルトユーザーまたは権限をグローバルに変更できます。アプリケーションが詳細なアクセスポリシーを必要とする場合: アクセスの制御にファイルシステム権限を使用しないことをお勧めします。代わりに、OSS サーバー側の認証システムを使用してパスの隔離を実装できます。たとえば、アプリケーションごとに異なる RAM ユーザーまたはロールを作成し、バケットポリシーまたはRAM ポリシーを使用して、アクセスできるサブパスを制限できます。パフォーマンスを最適化するために、
readdir_optimizeパラメーターは引き続き設定する必要があります。
ファイル書き込みモードの最適化
OSS オブジェクトのデフォルトの書き込み操作は上書きです。クライアントがファイルの変更を処理する場合、読み取り後の書き込みパターンに従う必要があります。まず、OSS からローカルマシンに完全なオブジェクトを読み取ります。次に、ファイルが閉じられた後、ファイル全体をサーバーに再アップロードします。したがって、頻繁なファイルのオープン、書き込み、クローズの極端なケースでは、アプリケーションは完全なデータを繰り返しダウンロードおよびアップロードします。
ソリューション:
複数の書き込みの代わりにバッチ書き込みを使用する: 可能な限り不要な複数の書き込みを避けてください。メモリ内でコンテンツを準備し、単一の書き込み操作を呼び出して完了させることができます。Java の
FileUtils.writeなどの一部のカプセル化された書き込み関数には、完全なopen、write、およびcloseフローがすでに含まれていることに注意してください。このような関数をループで繰り返し呼び出すと、パフォーマンスの問題が発生します。頻繁な変更には一時ファイルを使用する: データ処理タスク中にファイルを複数回開いて変更する必要がある場合は、まず OSS マウントポイントからコンテナー内の一時パス (
/tmpなど) にコピーできます。ローカルの一時ファイルですべての変更を実行します。最後に、最終バージョンを単一の操作で OSS マウントポイントにコピーしてアップロードできます。追加書き込みシナリオで追加可能機能を有効にする: アプリケーションシナリオがログの書き込みなど、頻繁で小さな追加書き込みのみを伴う場合は、ossfs 2.0 を使用し、
enable_appendable_object=trueパラメーターを有効にすることを検討できます。このパラメーターを有効にすると、クライアントは OSS 追加可能オブジェクトを使用します。データを追加するとき、クライアントは毎回ファイル全体をダウンロードして再アップロードする必要はありません。ただし、次の点に注意してください:オブジェクトファイルがすでに存在しているが、追加可能オブジェクトではない場合、このソリューションを使用してデータを追加することはできません。
enable_appendable_objectは、永続ボリューム全体に対するグローバルパラメーターです。有効にすると、このボリュームに対するすべての書き込み操作はAppendObjectAPI を介して実行されます。これは、大きなファイルの上書きパフォーマンスには影響しますが、読み取りには影響しません。このタイプの追加書き込みアプリケーションには、専用の永続ボリュームを作成することをお勧めします。
同時読み取りモードの最適化 (特にモデル読み込みシナリオ)
複数のプロセスが単一の大きなファイル内の異なる場所から同時にデータを読み取る場合、アクセスモードはランダム読み取りに似ています。これにより、クライアントが冗長にデータを読み取り、異常に高い帯域幅使用量につながる可能性があります。たとえば、AI モデルの読み込みシナリオでは、主流のモデルフレームワークは多くの場合、同じモデルパラメーターファイルを読み取る複数の同時プロセスを持ちます。これにより、パフォーマンスのボトルネックがトリガーされる可能性があります。
このようなシナリオで ossfs 2.0 のパフォーマンスが ossfs 1.0 よりも悪い場合、またはそのパフォーマンスが ossfs 2.0 クライアントのストレステストパフォーマンスと大幅に異なる場合は、これが問題であることを確認できます。
ソリューション:
データプリフェッチ (推奨): アプリケーション Pod が開始する前に、スクリプトを使用してデータをプリフェッチできます。コアとなる原理は、高帯域幅の同時シーケンシャル読み取りを使用して、モデルファイル全体を事前にノードのメモリ (ページキャッシュ) に読み込むことです。プリフェッチが完了すると、アプリケーションのランダム読み取りは直接メモリにヒットし、パフォーマンスのボトルネックをバイパスします。
次のスタンドアロンプリフェッチスクリプトを使用できます。これは、ファイルコンテンツを
/dev/nullに同時に読み取ります:#!/bin/bash # 最大同時実行数を設定します。 MAX_JOBS=4 # フォルダが引数として指定されているか確認します。 if [ -z "$1" ]; then echo "Usage: $0 <folder_path>" exit 1 fi DIR="$1" # フォルダが存在するか確認します。 if [ ! -d "$DIR" ]; then echo "Error: '$DIR' is not a valid folder." exit 1 fi # find を使用してすべての通常ファイルを検索し、xargs を使用して cat を /dev/null に同時に実行します。 find "$DIR" -type f -print0 | xargs -0 -I {} -P "$MAX_JOBS" sh -c 'cat "{}" > /dev/null' echo "Finished reading all files."このスクリプトのコアロジックを簡略化し、Pod の
lifecycle.postStartフックで実行できます。# ... spec: containers: - image: your-image env: # モデルファイルが配置されているフォルダパスを定義します。設定されていないか、フォルダが存在しない場合、スクリプトはデータプリフェッチをスキップします。 - name: MODEL_DIR value: /where/is/your/model/ # プリフェッチスクリプトの同時実行数を定義します。デフォルトは 4 です。 - name: PRELOADER_CONC value: "8" lifecycle: postStart: exec: command: ["/bin/sh", "-c", "CONC=${PRELOADER_CONC:-4}; if [ -d \"$MODEL_DIR\" ]; then find \"$MODEL_DIR\" -type f -print0 | xargs -0 -I {} -P \"$CONC\" sh -c 'cat \"{}\" > /dev/null'; fi"] # ...アプリケーションロジックのリファクタリング: アプリケーションロジックを評価およびリファクタリングして、単一ファイル内のマルチプロセス同時読み取りから、複数の異なるファイルの同時読み取りに切り替えることができます。この変更により、OSS の高スループットの利点を活用できます。
本番環境に関する推奨事項
クライアントの選択: アプリケーションに変更不可能なランダム書き込み要件がない限り、ossfs 2.0 永続ボリュームの使用を優先します。
モニタリングの優先: OSS バケットの帯域幅と QPS、ノードのネットワーク帯域幅、およびローカルディスク I/O (ossfs 1.0 の場合) を定期的にモニタリングします。これにより、パフォーマンスの問題が発生したときに迅速に特定できます。
キャッシュの無効化を回避する: アプリケーションが強力な整合性を必要としない限り、いかなる状況でもメタデータキャッシングを無効にしないでください。
データプリフェッチ: AI 推論など、大量のデータを読み取るシナリオでは、起動レイテンシーに対する要件が高い場合は、データプリフェッチソリューションの使用を検討できます。これにより、ノードのリソースと帯域幅が事前に占有されることに注意してください。
コストに関する考慮事項: OSS 永続ボリューム機能および関連コンポーネントは無料です。ただし、ストレージ容量、API リクエスト、アウトバウンドトラフィックなど、使用する基盤となる OSS リソースに対して課金されます。このトピックで言及されている、キャッシュの無効化やインターネットエンドポイントの使用などの不適切な設定やアプリケーションのアクセスモードは、API リクエストとトラフィックの急増を引き起こし、OSS の利用コストを増加させる可能性があります。
よくある質問
OSS 永続ボリュームがノードのローカルディスクよりはるかに遅いのはなぜですか?
これは正常です。OSS 永続ボリュームはネットワークファイルシステムです。すべての操作はネットワークとプロトコルの変換を経由する必要があります。そのレイテンシーとスループットは、直接接続されたローカルストレージとは異なります。パフォーマンス評価は、対応するベンチマークに基づいて行う必要があります。
アプリケーションの読み取りパフォーマンスは許容範囲内なのに、書き込みパフォーマンスが非常に悪いのはなぜですか?
これは通常、OSS オブジェクトの上書き専用の性質に関連しています。クライアントがファイルの変更を処理する場合、まずダウンロードし、次に変更し、最後にファイル全体をアップロードする必要があります。このプロセスはオーバーヘッドが高くなります。最適化情報については、「ファイル書き込みモードの最適化」をご参照ください。
アプリケーションがランダム書き込みを実行しているかどうかを判断するにはどうすればよいですか?
テスト環境では、アプリケーションによってマウントされる永続ボリュームタイプを ossfs 1.0 から ossfs 2.0 に切り替えることができます。アプリケーションの実行中にファイル書き込みに関連する EINVAL (無効な引数) エラーが発生した場合、ossfs 2.0 でサポートされていないランダム書き込み操作を実行していると判断できます。