再開可能なアップロード

設定

このページでは、Cloud Storage で再開可能なアップロードについて説明します。大容量のファイルのアップロードには再開可能なアップロードをおすすめします。アップロード中にネットワーク障害が発生した場合に、最初からファイルを再アップロードする必要はありません。

はじめに

再開可能なアップロードを使用すると、通信障害によってデータのフローが中断しても、Cloud Storage へのデータ転送オペレーションを再開できます。再開可能なアップロードでは、リクエストごとにアップロードするオブジェクトの一部が含まれる複数のリクエストを送信できます。これは、1 つのリクエストにオブジェクト データがすべて含まれ、このリクエストが途中で失敗した場合は最初からやり直す必要がある単一リクエストのアップロードとは異なります。

  • 再開可能なアップロードは、大容量のファイルをアップロードする場合や、低速の接続でアップロードする場合に使用してください。たとえば、再開可能なアップロードを使用する際のファイルサイズのカットオフについては、アップロード サイズに関する考慮事項をご覧ください。

  • 再開可能なアップロードは、開始から 1 週間以内に完了する必要がありますが、いつでもキャンセルできます。

  • 完了した再開可能なアップロードのみがバケットに表示されます。同じ名前のオブジェクトがすでに存在する場合は、既存のオブジェクトが置き換えられます。

ツールと API で再開可能なアップロードがどのように使用されるか

Cloud Storage の操作方法によっては、再開可能なアップロードが自動的に管理されることがあります。このセクションでは、さまざまなツールの再開可能なアップロード動作について説明し、アプリケーションに適したバッファサイズの構成に関するガイダンスを提供します。

Console

Google Cloud Console では、再開可能なアップロードを自動的に管理します。ただし、アップロードの進行中に Google Cloud コンソールで更新または移動を行うと、アップロードはキャンセルされます。

コマンドライン

gcloud CLI では、Cloud Storage にデータをアップロードするときに、gcloud storage cp コマンドと gcloud storage rsync コマンドで再開可能なアップロードを使用します。アップロードが中断した場合は、アップロードを開始する際に使用した同じコマンドを実行すると再開できます。複数のファイルを含むアップロードを再開する場合は、すでに正常に完了したファイルが再アップロードされないように --no-clobber フラグを使用します。

クライアント ライブラリ

再開可能なアップロードを実行する場合、クライアント ライブラリは Cloud Storage JSON API のラッパーとして機能します。

C++

storage::Client の関数は、さまざまな動作を実行します。

  • Client::WriteObject() は常に再開可能なアップロードを実行します。
  • Client::InsertObject() は常に単純なアップロードまたはマルチパート アップロードを実行します。
  • Client::UploadFile() は、再開可能なアップロード、単純なアップロード、マルチパート アップロードを実行できます。

デフォルトでは、オブジェクトが 20 MiB を超えると、UploadFile() は再開可能なアップロードを実行します。それ以外の場合は、単純なアップロードまたはマルチパート アップロードを実行します。このしきい値は、storage::Client の作成時に MaximumSimpleUploadsSizeOption を設定することで構成できます。

デフォルトのバッファサイズは 8 MiB です。これは、UploadBufferSizeOption オプションで変更できます。

C++ クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。バッファサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。WriteObject()UploadFile() を使用する場合は、アップロード速度とメモリ使用量のトレードオフを考慮することをおすすめします。サイズの小さいバッファを使用して大きなオブジェクトをアップロードすると、アップロードに時間がかかる可能性があります。C++ のアップロード速度とバッファサイズの関係については、GitHub の詳細な分析をご覧ください。

C#

アップロード時に、C# クライアント ライブラリは常に再開可能なアップロードを実行します。CreateObjectUploader で再開可能なアップロードを開始できます。

C# クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。デフォルトのバッファサイズは 10 MB です。この値は、UploadObjectOptionsChunkSize を設定することで変更できます。バッファサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、バッファサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。

Go

デフォルトでは、ファイルが 16 MiB を超えると、再開可能なアップロードが自動的に行われます。Writer.ChunkSize を使用して再開可能なアップロードを実行する場合のカットオフを変更します。Go クライアント ライブラリを使用すると、再開可能なアップロードは常にチャンク形式となります。

マルチパート アップロードでは、オブジェクトが Writer.ChunkSize より小さい場合、または Writer.ChunkSize が 0 に設定されている場合、チャンクが無効になります。ChunkSize が 0 に設定されている場合、Writerリクエストを再試行できません

Go クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。バッファサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、バッファサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。複数の再開可能なアップロードを同時に実行する場合は、メモリの肥大化を避けるため、Writer.ChunkSize を 16 MiB 未満の値に設定する必要があります。

Writer.Close() を呼び出して成功のレスポンスを受け取るまで、オブジェクトは Cloud Storage でファイナライズされません。リクエストが失敗した場合、Writer.Close はエラーを返します。

Java

Java クライアント ライブラリには、マルチパート アップロードと再開可能なアップロードに別々のメソッドがあります。次のメソッドでは、常に再開可能なアップロードを実行します。

デフォルトのバッファサイズは 15 MiB です。バッファサイズは、WriteChannel#setChunkSize(int) メソッドを使用するか、bufferSize パラメータを Storage#createFrom メソッドに渡すことで設定できます。バッファサイズの最小値は 256 KiB です。WriteChannel#setChunkSize(int) を内部で呼び出すと、バッファサイズは 256 KiB の倍数になります。

再開可能なアップロードのバッファリングは最小の埋め込みしきい値として機能し、バッファリングされた書き込みのバイト数がバッファサイズを超えるまで、バッファサイズより小さい書き込みはバッファリングされます。

アップロードするデータの量が少ない場合は、Storage#create(BlobInfo, byte[], Storage.BlobTargetOption...) または Storage#create(BlobInfo, byte[], int, int, Storage.BlobTargetOption...) の使用を検討してください。

Node.js

再開可能なアップロードは自動的に行われます。再開可能なアップロードをオフにするには、UploadOptionsresumablefalse に設定します。createWriteStream メソッドを使用している場合、再開可能なアップロードは自動的に管理されます。

デフォルトのバッファサイズはありません。チャンク形式アップロードは、CreateResumableUploadOptionschunkSize オプションを指定して手動で呼び出す必要があります。chunkSize を指定すると、データは個別の HTTP リクエストで送信されます。各リクエストには chunkSize サイズのペイロードが含まれます。chunkSize が指定されず、ライブラリが再開可能なアップロードを実行している場合、すべてのデータは単一の HTTP リクエストにストリーミングされます。

Node.js クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。バッファサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、バッファサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。

PHP

デフォルトでは、オブジェクト サイズが 5 MB を超えると、再開可能なアップロードが自動的に行われます。それ以外の場合は、マルチパート アップロードが行われます。このしきい値は変更できません。upload 関数で resumable オプションを設定すると、再開可能なアップロードを強制できます。

PHP クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。再開可能なアップロードのデフォルトのバッファサイズは 256 KiB です。このバッファサイズは、chunkSize プロパティを設定することで変更できます。バッファサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、バッファサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。

Python

再開可能なアップロードはオブジェクトが 8 MiB より大きい場合に行われ、マルチパート アップロードはオブジェクトが 8 MiB より小さい場合に行われます。このしきい値は変更できません。Python クライアント ライブラリは、チャンクサイズと同じバッファサイズを使用します。100 MiB は、再開可能なアップロードに使用されるデフォルトのバッファサイズです。バッファサイズは、blob.chunk_size プロパティを設定すると変更できます。

オブジェクトのサイズに関係なく、再開可能なアップロードを実行するには、クラス storage.BlobWriter またはメソッド storage.Blob.open(mode='w') を使用します。これらのメソッドの場合、デフォルトのバッファサイズは 40 MiB です。再開可能なメディアを使用して、再開可能なアップロードを管理することもできます。

チャンクサイズは 256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、チャンクサイズが大きくなるとアップロードが速くなりますが、速度とメモリ使用量にはトレードオフがあります。

Ruby

Ruby クライアント ライブラリでは、すべてのアップロードがチャンク化されていない再開可能なアップロードとして処理されます。

REST API

JSON API

Cloud Storage JSON API は、クエリ パラメータ uploadType=resumable を含む POST Object リクエストを使用して再開可能なアップロードを開始します。このリクエストは、セッション URI として返され、その後 1 つ以上の PUT Object リクエストでオブジェクト データをアップロードするために使用します。再開可能なアップロード用の独自のロジックを作成する詳しい手順については、再開可能なアップロードの実行をご覧ください。

XML API

Cloud Storage XML API は、ヘッダー x-goog-resumable: start を含む POST Object リクエストを使用して再開可能なアップロードを開始します。このリクエストは、セッション URI として返され、その後 1 つ以上の PUT Object リクエストでオブジェクト データをアップロードするために使用します。再開可能なアップロード用の独自のロジックを作成する詳しい手順については、再開可能なアップロードの実行をご覧ください。

不明なサイズの再開可能なアップロード

再開可能なアップロードのメカニズムでは、前もってファイルサイズがわからない場合の転送もサポートしています。これは、アップロード中にオブジェクトを圧縮する場合などに便利です。圧縮したファイルの正確なファイルサイズを転送の開始時点で予測することは難しいからです。このメカニズムは、中断後に再開可能な転送をストリーミングする場合や、チャンク転送エンコードがアプリケーションで機能しない場合に活用できます。

詳細については、ストリーミング アップロードをご覧ください。

アップロードのパフォーマンス

セッション リージョンの選択

再開可能なアップロードは、それを開始したリージョンに固定されます。たとえば、米国で再開可能なアップロードを開始し、アジアのクライアントにセッション URI を渡した場合でも、アップロード自体は米国で実行されます。リージョン間のトラフィックを削減してパフォーマンスを向上させるには、作成元のリージョンで再開可能なアップロード セッションを維持する必要があります。

Compute Engine インスタンスを使用して再開可能なアップロードを開始する場合、インスタンスはアップロード先の Cloud Storage バケットと同じロケーションに存在する必要があります。次に geo IP サービスを使って、顧客のリクエストのルーティング先となる Compute Engine のリージョンを取得することで、地理上の地域にトラフィックを局所化できます。

チャンク形式でのアップロード

可能であれば、転送を小さなチャンクに分割せずに、コンテンツ全体を 1 つのチャンクでアップロードしてください。チャンクへの分割を避けることで、各チャンクに保存されたオフセットを取得する必要がなくなるため、追加のレイテンシや使用料金が発生することなく、スループットも向上します。ただし、次の場合はチャンクでアップロードすることを検討してください。

  • ソースデータが動的に生成され、かつ、アップロードが失敗した場合に備えてクライアント側でバッファするデータの量を制限する場合。

  • 多くのブラウザと同様に、クライアントにリクエスト サイズの制限がある場合。

JSON API または XML API を使用していて、クライアントがエラーを受け取った場合、維持されたオフセットをサーバーに照会し、そのオフセットから残りのバイトのアップロードを再開できます。これは、Google Cloud コンソール、Google Cloud CLI、クライアント ライブラリによって自動的に処理されます。特定のクライアント ライブラリのチャンクの詳細については、ツールと API で再開可能なアップロードがどのように使用されるかをご覧ください。

考慮事項

このセクションは、再開可能なアップロード リクエストを JSON または XML API に直接送信する独自のクライアントを構築するのに役立ちます。

セッション URI

再開可能なアップロードを開始すると、Cloud Storage がセッション URI を返します。この URI は、後続のリクエストで使用する実際のデータをアップロードするために使用します。JSON API でのセッション URI の例を次に示します。

https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=resumable&name=my-file.jpg&upload_id=ABg5-UxlRQU75tqTINorGYDgM69mX06CzKO1NRFIMOiuTsu_mVsl3E-3uSVz65l65GYuyBuTPWWICWkinL1FWcbvvOA

XML API でのセッション URI の例を次に示します。

 https://storage.googleapis.com/my-bucket/my-file.jpg?upload_id=ABg5-UxlRQU75tqTINorGYDgM69mX06CzKO1NRFIMOiuTsu_mVsl3E-3uSVz65l65GYuyBuTPWWICWkinL1FWcbvvOA

このセッション URI は認証トークンとして機能するため、このトークンを使用するリクエストには署名の必要がなく、追加の認証を行わずに誰でもそのターゲット バケットにデータをアップロードできます。このため、セッション URI の共有は慎重に行い、HTTPS 経由でのみ共有してください。

セッション URI は 1 週間後に期限切れになりますが、期限切れになる前にキャンセルできます。無効になったセッション URI を使用してリクエストを行うと、次のいずれかのエラーが返されます。

  • 410 Gone ステータス コード。アップロードが開始されてから 1 週間未満の場合。
  • 404 Not Found ステータス コード。アップロードが開始されてから 1 週間以上経過している場合。

いずれの場合でも、再開可能なアップロードを新たに開始して新しいセッション URI を取得し、新しいセッション URI を使用してアップロードを最初からやり直す必要があります。

整合性チェック

最終的にアップロードされたオブジェクトの整合性をチェックして、ソースファイルと一致するかどうかを確認することをおすすめします。これを行うには、ソースファイルの MD5 ダイジェストを計算し、その値を Content-MD5 リクエスト ヘッダーの値と比較します。

アップロードされたファイルの整合性をチェックすることは、大容量のファイルを長時間かけてアップロードするときに特に重要です。ソースファイルがアップロード操作の過程で変更される可能性が高いからです。

再試行とデータの再送

Cloud Storage によって、再開可能なアップロードのバイトが保持されると、それらのバイトは上書きできなくなり、Cloud Storage では上書きの試行が無視されます。そのため、以前に送信したオフセットに逆戻りするときに、別のデータを送信する必要はありません。

たとえば、100,000 バイトのオブジェクトをアップロードし、接続が中断されたとします。ステータスを確認すると、50,000 バイトが正常にアップロードされ、永続化されていることがわかります。40,000 バイトでアップロードを再開しようとすると、Cloud Storage は 40,000 バイト~50,000 バイトで送信されたバイトを無視します。Cloud Storage は、送信したデータの永続化をバイト 50,001 で開始します。

次のステップ