このページでは、Cloud Storage で再開可能なアップロードについて説明します。大容量のファイルのアップロードには再開可能なアップロードをおすすめします。アップロード中にネットワーク障害が発生した場合に、最初からファイルを再アップロードする必要はありません。
はじめに
再開可能なアップロードを使用すると、通信障害によってデータのフローが中断しても、Cloud Storage へのデータ転送オペレーションを再開できます。再開可能なアップロードでは、リクエストごとにアップロードするオブジェクトの一部が含まれる複数のリクエストを送信できます。これは、1 つのリクエストにオブジェクト データがすべて含まれ、このリクエストが途中で失敗した場合は最初からやり直す必要がある単一リクエストのアップロードとは異なります。
再開可能なアップロードは、大容量のファイルをアップロードする場合や、低速の接続でアップロードする場合に使用してください。たとえば、再開可能なアップロードを使用する際のファイルサイズのカットオフについては、アップロード サイズに関する考慮事項をご覧ください。
再開可能なアップロードは、開始から 1 週間以内に完了する必要がありますが、いつでもキャンセルできます。
完了した再開可能なアップロードのみがバケットに表示されます。同じ名前のオブジェクトがすでに存在する場合は、既存のオブジェクトが置き換えられます。
オブジェクトの作成時間はアップロードの完了時間に基づきます。
ユーザーが設定したオブジェクト メタデータは最初のリクエストで指定します。このメタデータは、アップロードの完了時にオブジェクトに適用されます。
リクエストに
X-Goog-Meta-
というヘッダーが含まれている場合、JSON API の最後のリクエストでカスタム メタデータを設定できます。
- 完了した再開可能なアップロードは、1 つのクラス A オペレーションとみなされます。
ツールと API で再開可能なアップロードがどのように使用されるか
Cloud Storage の操作方法によっては、再開可能なアップロードが自動的に管理されることがあります。このセクションでは、さまざまなツールの再開可能なアップロード動作について説明し、アプリケーションに適したバッファサイズの構成に関するガイダンスを提供します。
コンソール
Google Cloud コンソールでは、再開可能なアップロードを自動的に管理します。ただし、アップロードの進行中に Google Cloud コンソールで更新または移動を行うと、アップロードはキャンセルされます。
コマンドライン
gcloud CLI では、Cloud Storage にデータをアップロードするときに、gcloud storage cp
コマンドと gcloud storage rsync
コマンドで再開可能なアップロードを使用します。アップロードが中断した場合は、アップロードを開始する際に使用した同じコマンドを実行すると再開できます。複数のファイルを含むアップロードを再開する場合は、すでに正常に完了したファイルが再アップロードされないように --no-clobber
フラグを使用します。
クライアント ライブラリ
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 です。この値は、UploadObjectOptions
で ChunkSize
を設定することで変更できます。バッファサイズは 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 クライアント ライブラリには、マルチパート アップロードと再開可能なアップロードに別々のメソッドがあります。次のメソッドでは、常に再開可能なアップロードを実行します。
Storage#createFrom(BlobInfo, java.io.InputStream, Storage.BlobWriteOption...)
Storage#createFrom(BlobInfo, java.io.InputStream, int, Storage.BlobWriteOption...)
Storage#createFrom(BlobInfo, java.nio.file.Path, Storage.BlobWriteOption...)
Storage#createFrom(BlobInfo, java.nio.file.Path, int, Storage.BlobWriteOption...)
Storage#writer(BlobInfo, Storage.BlobWriteOption...)
Storage#writer(java.net.URL)
デフォルトのバッファサイズは 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
再開可能なアップロードは自動的に行われます。再開可能なアップロードをオフにするには、UploadOptions
で resumable
を false
に設定します。createWriteStream
メソッドを使用している場合、再開可能なアップロードは自動的に管理されます。
デフォルトのバッファサイズはありません。チャンク形式アップロードは、CreateResumableUploadOptions の chunkSize
オプションを指定して手動で呼び出す必要があります。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
リクエスト ヘッダーの値と比較します。
アップロードされたファイルの完全性をチェックすることは、大容量のファイルを長時間かけてアップロードするときに特に重要です。ソースファイルがアップロード操作の過程で変更される可能性が高いからです。
再開可能なアップロードを開始するときは、x-goog-content-sha256
値が無視されます。そのため、x-goog-content-sha256
を UNSIGNED-PAYLOAD
に設定することをおすすめします。
再試行とデータの再送
Cloud Storage によって、再開可能なアップロードのバイトが保持されると、それらのバイトは上書きできなくなり、Cloud Storage では上書きの試行が無視されます。そのため、以前に送信したオフセットに逆戻りするときに、別のデータを送信する必要はありません。
たとえば、100,000 バイトのオブジェクトをアップロードし、接続が中断されたとします。ステータスを確認すると、50,000 バイトが正常にアップロードされ、永続化されていることがわかります。40,000 バイトでアップロードを再開しようとすると、Cloud Storage は 40,000 バイト~50,000 バイトで送信されたバイトを無視します。Cloud Storage は、送信したデータの永続化をバイト 50,001 で開始します。
次のステップ
- 再開可能なアップロードを実行する。
- Cloud Storage へのリクエストの再試行について学習する。
- Cloud Storage への他のタイプのアップロードについて確認する。