Python を使用したアップロードとダウンロードのパフォーマンス チューニング
アプリケーションが Python 用 Azure Storage クライアント ライブラリを使ってデータを転送する場合、要求の速度、メモリ使用量、さらには成功または失敗に影響を与える可能性のあるいくつかの要因があります。 データ転送のパフォーマンスと信頼性を最大にするには、アプリが実行される環境に基づいて、クライアント ライブラリ転送オプションを事前に構成することが重要です。
この記事では、データ転送オプションのチューニングに関するいくつかの考慮事項について説明します。 クライアント ライブラリを適切にチューニングすると、複数の要求にデータを効率的に分散できるため、操作速度、メモリ使用量、ネットワークの安定性が向上する可能性があります。
アップロードのパフォーマンス チューニング
データ転送オプションを適切に調整することは、アップロードのパフォーマンスの信頼性の鍵となります。 ストレージ転送は、これらの引数の値に基づいて、複数のサブ転送に分割されます。 サポートされる最大転送サイズは、操作とサービスのバージョンによって異なるため、ドキュメントを調べて制限を確認してください。 Blob Storage での転送サイズの制限について詳しくは、「BLOB ストレージのスケール ターゲット」をご覧ください。
アップロードの転送オプションを設定する
次の引数は、アプリのニーズに基づいて調整できます。
- max_single_put_size: 1 つの要求でアップロードされる BLOB の最大サイズ。 既定値は 64 MiB です。
- max_block_size: ブロック BLOB をチャンク単位でアップロードするときの転送の最大長 (バイト単位)。 既定値は 4 MiB です。
max_concurrency
: 並列で使用できるサブ転送の最大数。
注意
指定されていない場合、各データ転送オプションの既定値がクライアント ライブラリで使用されます。 通常、これらの既定値は、データ センター環境でのパフォーマンスは優れていますが、ホーム コンシューマー環境には適していない可能性があります。 データ転送オプションの調整が不十分な場合、処理時間が非常に長くなる可能性があり、要求がタイムアウトすることさえあります。 これらの値を事前にテストし、アプリケーションと環境のニーズに基づいて調整することをお勧めします。
max_single_put_size
max_single_put_size
引数は、1 回の要求のアップロードの最大 BLOB サイズ (バイト単位) です。 BLOB サイズが max_single_put_size
以下 の場合、BLOB は 1 つの Put Blob 要求でアップロードされます。 BLOB サイズが max_single_put_size
より大きい場合、または BLOB サイズが不明な場合、BLOB は一連の Put Block 呼び出しの後に Put Block List を使用してチャンク単位でアップロードされます。
max_block_size
に指定する値は、max_single_put_size
に対して定義する値を "制限しない" ことに注意してください。 max_single_put_size
引数では、操作全体をサブ転送なしで一度に実行するための、1 つの要求の個別のサイズ制限を定義します。 多くの場合、max_single_put_size
は、max_block_size
に対して定義した値より大きくはないにしても、"少なくとも" それと同じ大きさにする必要があります。 データ転送のサイズによっては、このようにすると、転送が 1 つの要求で完了し、複数の要求のオーバーヘッドが回避されるため、パフォーマンスが向上する可能性があります。
状況に最適な値がわからない場合は、max_block_size
に使われているのと同じ値に max_single_put_size
を設定するのが安全なオプションです。
max_block_size
max_block_size
引数は、ブロック BLOB をチャンク単位でアップロードするときの転送の最大長 (バイト単位) です。 前に説明したように、この値によって max_single_put_size
が制限されることは "なく"、max_block_size
より大きくできます。
データ移動の効率性を維持するため、クライアント ライブラリではすべての転送で max_block_size
値に常に達するとは限りません。 転送サイズでサポートされる最大値は、操作によって異なる場合があります。 Blob Storage での転送サイズの制限について詳しくは、「BLOB ストレージのスケール ターゲット」の表をご覧ください。
コードの例
次のコード例は、BlobClient
オブジェクトの作成時にデータ転送オプションを指定する方法と、そのクライアント オブジェクトを使用してデータをアップロードする方法を示しています。 このサンプルで提供される値は、推奨を意図したものではありません。 これらの値を適切にチューニングするには、アプリの特定のニーズを考慮する必要があります。
def upload_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
# Create a BlobClient object with data transfer options for upload
blob_client = BlobClient(
account_url=account_url,
container_name=container_name,
blob_name=blob_name,
credential=DefaultAzureCredential(),
max_block_size=1024*1024*4, # 4 MiB
max_single_put_size=1024*1024*8 # 8 MiB
)
with open(file=os.path.join(r'file_path', blob_name), mode="rb") as data:
blob_client = blob_client.upload_blob(data=data, overwrite=True, max_concurrency=2)
この例では、メソッド呼び出しの max_concurrency
引数を使って、並列転送ワーカーの数を 2 に設定しています。 この構成では、最大 2 つの接続が同時に開かれ、アップロードを並列で実行できます。 クライアントのインスタンス化時に、max_single_put_size
引数を 8 MiB に設定します。 BLOB のサイズが 8 MiB 未満の場合、アップロード操作を完了するために必要な要求は 1 つだけです。 BLOB サイズが 8 MiB を超える場合、max_block_size
引数によって設定された最大チャンク サイズ 4 MiB のチャンク単位で BLOB が アップロードされます。
アップロードのパフォーマンスに関する考慮事項
アップロード時に、Storage クライアント ライブラリは、クライアントの構築時に定義された構成オプションに基づいて、特定のアップロード ストリームを複数のサブアップロードに分割します。 REST 操作は、サブアップロードごとに専用の呼び出しで行われます。 BlobClient
オブジェクトの場合、この操作は Put Block です。 ストレージ クライアント ライブラリによって、これらの REST 操作が (転送オプションに応じて) 並列に管理されて、完全なアップロードが実行されます。
クライアント ライブラリがバッファリングをどのように処理するかについては、次のセクションで説明します。
Note
ブロック BLOB の最大ブロック数は 50,000 ブロックです。 したがって、ブロック BLOB の最大サイズは max_block_size
の 50,000 倍です。
アップロードの間のバッファーリング
Storage REST レイヤーでは、中断した REST アップロード操作の取得はサポートされていません。転送ごとに完了するか、失われます。 ストリーム アップロードの回復性を確保するため、ストレージ クライアント ライブラリは、アップロードを始める前に、個々の REST 呼び出しごとにデータをバッファーに格納します。 ネットワーク速度の制限だけでなく、このバッファーリング動作も、順番にアップロードする場合であっても、max_block_size
の値を小さくすることを検討すべき理由です。 max_block_size
の値を小さくすると、各要求および失敗した要求の各再試行でバッファーに格納されるデータの最大量が減ります。 あるサイズのデータ転送中にタイムアウトが頻繁に発生する場合は、max_block_size
の値を小さくすると、バッファーリング時間が短縮され、パフォーマンスが向上する可能性があります。
既定では、SDK は同時サブアップロード要求ごとに max_block_size
バイトのデータをバッファーに格納しますが、次の条件が満たされた場合、メモリ使用量は要求あたり 4 MiB に制限できます。
max_block_size
引数はmin_large_block_upload_threshold
より大きくなければなりません。min_large_block_upload_threshold
引数は、クライアントのインスタンス化中に定義でき、メモリ効率の高いアルゴリズムを使用するために必要な最小チャンク サイズ (バイト単位) です。min_large_block_upload_threshold
引数の既定値は4*1024*1024 + 1
です。- 指定されたストリームはシーク可能である必要があります。 シーク可能なストリームとは、ストリーム内の現在位置でのクエリと変更をサポートするストリームです。
- BLOB はブロック BLOB である必要があります。
この方法はほとんどの状況に適用されますが、バッファリングを必要とする他のクライアント ライブラリ機能がコードで使われている場合は、バッファリングがさらに発生する可能性があります。
ダウンロードのパフォーマンス チューニング
データ転送オプションを適切に調整することは、ダウンロードのパフォーマンスの信頼性の鍵となります。 ストレージ転送は、これらの引数の値に基づいて、複数のサブ転送に分割されます。
ダウンロードの転送オプションを設定する
次の引数は、アプリのニーズに基づいて調整できます。
max_chunk_get_size
: BLOB のダウンロードに使用される最大チャンク サイズ。 既定値は 4 MiB です。max_concurrency
: 並列で使用できるサブ転送の最大数。max_single_get_size
: 1 回の呼び出しでダウンロードされる BLOB の最大サイズ。 BLOB の合計サイズがmax_single_get_size
を超える場合、BLOB データの残りの部分はチャンクでダウンロードされます。 既定値は 32 MiB です。
コードの例
def download_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
# Create a BlobClient object with data transfer options for download
blob_client = BlobClient(
account_url=account_url,
container_name=container_name,
blob_name=blob_name,
credential=DefaultAzureCredential(),
max_single_get_size=1024*1024*32, # 32 MiB
max_chunk_get_size=1024*1024*4 # 4 MiB
)
with open(file=os.path.join(r'file_path', 'file_name'), mode="wb") as sample_blob:
download_stream = blob_client.download_blob(max_concurrency=2)
sample_blob.write(download_stream.readall())
ダウンロードのパフォーマンスに関する考慮事項
ダウンロード時に、Storage クライアント ライブラリは、クライアントの構築時に定義された構成オプションに基づいて、特定のダウンロード要求を複数のサブダウンロードに分割します。 REST 操作は、サブダウンロードごとに専用の呼び出しで行われます。 転送オプションに応じて、クライアント ライブラリにより、これらの REST 操作が並列に管理されて、完全なダウンロードが実行されます。
ダウンロードの max_single_get_size
ダウンロードの間に、ストレージ クライアント ライブラリは、他の操作を行う前に、max_single_get_size
を使ってダウンロード範囲要求を 1 回行います。 この最初のダウンロード要求中に、クライアント ライブラリはリソースの合計サイズを把握します。 最初の要求ですべてのコンテンツが正常にダウンロードされた場合、操作は完了します。 そうでない場合、クライアント ライブラリは、完全なダウンロードが完了するまで、最大 max_chunk_get_size
の範囲要求を実行し続けます。
次のステップ
- Azure Storage の操作のパフォーマンスに影響を与える可能性のある要因について詳しくは、「Blob Storage での待ち時間」をご覧ください。
- Blob Storage を使用するアプリのパフォーマンスを最適にするための設計に関する考慮事項の一覧については、「BLOB ストレージのパフォーマンスとスケーラビリティのチェックリスト」をご覧ください。