このページでは、失敗したリクエストを Cloud Storage ツールが再試行する方法と、再試行の動作をカスタマイズする方法について説明します。また、リクエストを再試行する際の考慮事項についても説明します。
概要
リクエストの再試行が安全かどうかは、次の 2 つの要素で決まります。
- リクエストからの受信レスポンス。
- リクエストのべき等性。
レスポンス
リクエストから返されたレスポンスは、リクエストの再試行に役立つかどうかを示します。通常、一時的な問題に関連するレスポンスは再試行できます。一方、永続的なエラーに関連するレスポンスは、リクエストを再試行する前に、承認や構成の変更などを行う必要があることを示します。次のレスポンスは、再試行する価値がある一時的な問題を示しています。
408
、429
、5xx
の HTTP レスポンス コード。- ソケット タイムアウトと TCP 切断。
詳細については、JSON と XML のステータス コードとエラーコードをご覧ください。
べき等性
リクエストがべき等であることは、リクエストを繰り返し実行しても、対象となるリソースが常に同じ終了状態になることを意味します。たとえば、一覧表示のリクエストは、リソースを変更しないので、常にべき等です。一方、新しい Pub/Sub 通知の作成はべき等ではありません。リクエストが成功するたびに新しい通知 ID が生成されるためです。
以下に、オペレーションをべき等にする条件の例を示します。
オペレーションを連続してリクエストしても、対象リソースに対して結果が生成される。
オペレーションが 1 回だけ成功する。
対象リソースの状態に対して観察可能な結果がない。
再試行可能なレスポンスを受け取った場合は、リクエストのべき等性を考慮する必要があります。これは、べき等でないリクエストを再試行すると、競合状態などの競合が発生する可能性があるためです。
条件付きべき等性
リクエストのサブセットは条件付きべき等性になります。つまり、特定のオプション引数が含まれる場合にのみ、べき等になります。条件付きで安全に再試行できるオペレーションは、条件のケースに該当した場合にのみデフォルトで再試行されます。Cloud Storage は、リクエストの条件ケースとして前提条件と ETag を受け入れます。
オペレーションのべき等性
次の表に、べき等性の各カテゴリに属する Cloud Storage オペレーションの一覧を示します。
べき等性 | オペレーション |
---|---|
常にべき等 |
|
条件付きべき等性 |
|
べき等でない |
|
1 このフィールドは JSON API で使用できます。クライアント ライブラリで使用できるフィールドについては、関連するクライアント ライブラリのドキュメントをご覧ください。
Cloud Storage ツールの再試行方法の実装方法
コンソール
Google Cloud コンソールが Cloud Storage にリクエストを送信し、必要なバックオフを処理します。
コマンドライン
gcloud storage
コマンドは、レスポンス セクションに示されているエラーを再試行します。追加のアクションを行う必要はありません。次のようなエラーに対しては、対応が必要になる場合があります。
認証情報が無効であるか、十分な権限がない。
プロキシ構成の問題でネットワークに接続できない。
再試行可能なエラーの場合、gcloud CLI は切り捨てバイナリ指数バックオフを使用してリクエストを再試行します。gcloud CLI の場合、デフォルトの再試行の最大数は 32 です。
クライアント ライブラリ
C++
デフォルトでは、次の HTTP エラーコードに対する再試行と、接続が切断または正常に確立されなかったことを示すソケットエラーに対する再試行がサポートされます。
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
C++ ライブラリの指数バックオフと再試行のすべての設定を構成できます。ライブラリで実装されているアルゴリズムが要件に合わない場合は、カスタムコードを作成して独自の戦略を実装できます。
設定 | デフォルト値 |
---|---|
自動再試行 | True |
リクエストの再試行の最大時間 | 15 分 |
初期待機(バックオフ)時間 | 1 秒 |
反復処理ごとの待機時間乗数 | 2 |
最大待機時間 | 5 分 |
デフォルトでは、C++ ライブラリは再試行可能なエラーですべてのオペレーションを再試行します。また、べき等にすることなく、繰り返し成功したときに複数のリソースを削除または作成できます。べき等オペレーションのみを再試行するには、google::cloud::storage::StrictIdempotencyPolicy
クラスを使用します。
C#
C# クライアント ライブラリは、デフォルトで指数バックオフを使用します。
Go
デフォルトでは、オペレーションは次のエラーの再試行をサポートします。
- 接続エラー:
io.ErrUnexpectedEOF
: これは、一時的なネットワークの問題が原因で発生する可能性があります。connection refused
を含むurl.Error
: これは、一時的なネットワークの問題が原因で発生する可能性があります。connection reset by peer
を含むurl.Error
: Google Cloud が接続をリセットしたことを意味します。net.ErrClosed
: Google Cloud が接続を閉じていることを意味します。
- HTTP コード:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Temporary()
インターフェースを実装し、値をerr.Temporary() == true
に設定する際のエラー- Go 1.13 エラー ラッピングを使用してラップされた上記のエラーのいずれか
Go ライブラリでは、すべての指数バックオフ設定が構成可能です。デフォルトでは、Go によるオペレーションでは指数バックオフ用に次の設定が使用されます(デフォルトは gax から取得されます)。
設定 | デフォルト値(秒) |
---|---|
自動再試行 | べき等の場合は true |
最大試行回数 | 上限なし |
最初の再試行までの経過時間 | 1 秒 |
再試行遅延乗数 | 2.0 |
再試行の最大遅延 | 30 秒 |
合計タイムアウト(再開可能なチャンク アップロード) | 32 秒 |
合計タイムアウト(他のすべてのオペレーション) | 上限なし |
一般に、制御コンテキストがキャンセルされるか、クライアントが終了するか、一時的でないエラーが受信されない限り、再試行は無期限に続行されます。再試行の続行を停止するには、コンテキストのタイムアウトまたはキャンセルを使用します。この動作の唯一の例外は、書き込みを使用して再開可能なアップロードを実行する場合です。この場合、データ量が十分にあり、複数のリクエストが必要になります。このシナリオでは、各チャンクがタイムアウトし、デフォルトで 32 秒後に再試行を停止します。デフォルトのタイムアウトは Writer.ChunkRetryDeadline
を変更することで調整できます。
条件付きべき等(条件付きで安全に再試行できる)の Go オペレーションのサブセットがあります。これらのオペレーションは、次の特定の条件を満たす場合にのみ再試行されます。
GenerationMatch
またはGeneration
- 前提条件
GenerationMatch
が呼び出しに適用されていた場合、またはObjectHandle.Generation
が設定されていた場合は、再試行しても安全です。
- 前提条件
MetagenerationMatch
- 前提条件
MetagenerationMatch
が呼び出しに適用されていた場合は、再試行しても安全です。
- 前提条件
Etag
- メソッドが
etag
を JSON リクエスト本文に挿入する場合は、安全に再試行できます。HmacKeyMetadata.Etag
が設定されている場合にのみ、HMACKeyHandle.Update
で使用されます。
- メソッドが
RetryPolicy
はデフォルトで RetryPolicy.RetryIdempotent
に設定されています。デフォルトの再試行動作を変更する方法の例については、再試行のカスタマイズをご覧ください。
Java
デフォルトでは、オペレーションは次のエラーの再試行をサポートします。
- 接続エラー:
Connection reset by peer
: Google Cloud が接続をリセットしたことを意味します。Unexpected connection closure
: Google Cloud が接続を閉じていることを意味します。
- HTTP コード:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Java ライブラリでは、すべての指数バックオフ設定が構成可能です。デフォルトでは、Java によるオペレーションでは指数バックオフ用に次の設定が使用されます。
設定 | デフォルト値(秒) |
---|---|
自動再試行 | べき等の場合は true |
最大試行回数 | 6 |
最初の再試行までの経過時間 | 1 秒 |
再試行遅延乗数 | 2.0 |
再試行の最大遅延 | 32 秒 |
合計タイムアウト | 50 秒 |
初期 RPC タイムアウト | 50 秒 |
RPC タイムアウト乗数 | 1.0 |
最大 RPC タイムアウト | 50 秒 |
接続タイムアウト | 20 秒 |
読み取りタイムアウト | 20 秒 |
設定の詳細については、Java リファレンス ドキュメントの RetrySettings.Builder
と HttpTransportOptions.Builder
をご覧ください。
条件付きべき等(条件付きで安全に再試行できる)の Java オペレーションのサブセットがあります。これらのオペレーションは、特定の引数が含まれている場合にのみ再試行されます。
ifGenerationMatch
またはgeneration
- メソッドに
ifGenerationMatch
またはgeneration
がオプションとして渡された場合は、安全に再試行できます。
- メソッドに
ifMetagenerationMatch
ifMetagenerationMatch
がオプションとして渡された場合は、安全に再試行できます。
StorageOptions.setStorageRetryStrategy
はデフォルトで StorageRetryStrategy#getDefaultStorageRetryStrategy
に設定されています。
デフォルトの再試行動作を変更する方法の例については、再試行のカスタマイズをご覧ください。
Node.js
オペレーションでは、デフォルトで次のエラーコードの再試行がサポートされています。
- 接続エラー:
EAI_again
: これは DNS ルックアップ エラーです。詳細については、getaddrinfo
のドキュメントをご覧ください。Connection reset by peer
: Google Cloud が接続をリセットしたことを意味します。Unexpected connection closure
: Google Cloud が接続を閉じていることを意味します。
- HTTP コード:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Node.js ライブラリでは、すべての指数バックオフ設定が構成可能です。デフォルトで、Node.js を使用したオペレーションでは、指数バックオフに次の設定を使用します。
設定 | デフォルト値(秒) |
---|---|
自動再試行 | べき等の場合は true |
再試行の最大回数 | 3 |
初期待機時間 | 1 秒 |
反復処理ごとの待機時間乗数 | 2 |
最大待機時間 | 64 秒 |
デフォルトの期限 | 600 秒 |
条件付きべき等である(条件付きで安全に再試行できる)Node.js オペレーションのサブセットがあります。これらのオペレーションは、特定の引数が含まれている場合にのみ再試行されます。
ifGenerationMatch
またはgeneration
- メソッドに
ifGenerationMatch
またはgeneration
がオプションとして渡された場合は、安全に再試行できます。多くの場合、メソッドは一方のパラメータのみ受け入れます。
- メソッドに
ifMetagenerationMatch
ifMetagenerationMatch
がオプションとして渡された場合は、安全に再試行できます。
retryOptions.idempotencyStrategy
はデフォルトで IdempotencyStrategy.RetryConditional
に設定されています。デフォルトの再試行動作を変更する方法の例については、再試行のカスタマイズをご覧ください。
PHP
PHP クライアント ライブラリは、デフォルトで指数バックオフを使用します。
Python
オペレーションでは、デフォルトで次のエラーコードの再試行がサポートされています。
- 接続エラー:
requests.exceptions.ConnectionError
requests.exceptions.ChunkedEncodingError
(アップロードやダウンロードなどペイロード データをフェッチまたは送信するオペレーションのみ)ConnectionError
- HTTP コード:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Python によるオペレーションでは、指数バックオフとして次のデフォルト設定が使用されます。
設定 | デフォルト値(秒) |
---|---|
自動再試行 | べき等の場合は true |
初期待機時間 | 1 |
反復処理ごとの待機時間乗数 | 2 |
最大待機時間 | 60 |
デフォルトの期限 | 120 |
特定の引数が含まれている場合、条件付きべき等(条件付きで安全に再試行できる)である Python オペレーションのサブセットがあります。これらのオペレーションは、条件のケースに一致した場合にのみ再試行されます。
DEFAULT_RETRY_IF_GENERATION_SPECIFIED
- メソッドに
generation
またはif_generation_match
が引数として渡された場合は、安全に再試行できます。多くの場合、メソッドはいずれかのパラメータを受け入れます。
- メソッドに
DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
- メソッドに
if_metageneration_match
が引数として渡された場合は、安全に再試行できます。
- メソッドに
DEFAULT_RETRY_IF_ETAG_IN_JSON
- メソッドが
etag
を JSON リクエスト本文に挿入する場合は、安全に再試行できます。HMACKeyMetadata.update()
の場合は、HMACKeyMetadata
オブジェクト自体に etag を設定する必要があります。他のクラスのset_iam_policy()
メソッドの場合は、メソッドに渡される「policy」引数に etag を設定する必要があります。
- メソッドが
Ruby
オペレーションでは、デフォルトで次のエラーコードの再試行がサポートされています。
- 接続エラー:
SocketError
HTTPClient::TimeoutError
Errno::ECONNREFUSED
HTTPClient::KeepAliveDisconnected
- HTTP コード:
408 Request Timeout
429 Too Many Requests
5xx Server Error
Ruby クライアント ライブラリでは、すべての指数バックオフ設定が構成可能です。Ruby クライアント ライブラリを介したオペレーションでは、デフォルトで指数バックオフ用に次の設定が使用されます。
設定 | デフォルト値 |
---|---|
自動再試行 | True |
最大再試行回数 | 3 |
初期待機時間 | 1 秒 |
反復処理ごとの待機時間乗数 | 2 |
最大待機時間 | 60 秒 |
デフォルトの期限 | 900 秒 |
特定の引数が含まれている場合、条件付きべき等(条件付きで安全に再試行できる)である Ruby オペレーションのサブセットがあります。
if_generation_match
またはgeneration
- メソッドに
generation
またはif_generation_match
パラメータが引数として渡された場合は、安全に再試行できます。多くの場合、メソッドはいずれかのパラメータを受け入れます。
- メソッドに
if_metageneration_match
if_metageneration_match
パラメータがオプションとして渡された場合は、安全に再試行できます。
デフォルトでは、すべてのべき等オペレーションは再試行され、条件付きべき等オペレーションは、条件ケースが満たされた場合にのみ再試行されます。べき等以外のオペレーションは再試行されません。デフォルトの再試行動作を変更する方法の例については、再試行のカスタマイズをご覧ください。
REST API
JSON または XML API を直接呼び出す場合は、指数バックオフ アルゴリズムを使用して独自の再試行方法を実装する必要があります。
再試行をカスタマイズする
コンソール
再試行の動作のカスタマイズに、Google Cloud コンソールを使用することはできません。
コマンドライン
gcloud storage
コマンドの場合、名前付き構成を作成し、次のプロパティの一部またはすべてを設定することで、再試行方法を制御できます。
base_retry_delay
exponential_sleep_multiplier
max_retries
max_retry_delay
次に、コマンドごとにプロジェクト全体のフラグ --configuration
を使用するか、すべての gcloud コマンドに gcloud config set
コマンドを使用して構成を適用します。
クライアント ライブラリ
C++
再試行動作をカスタマイズするには、google::cloud::storage::Client
オブジェクトの初期化時に次のオプションを指定します。
google::cloud::storage::RetryPolicyOption
: このライブラリはgoogle::cloud::storage::LimitedErrorCountRetryPolicy
クラスとgoogle::cloud::storage::LimitedTimeRetryPolicy
クラスを提供します。独自のクラスを指定できますが、その場合、google::cloud::RetryPolicy
インターフェースを実装する必要があります。google::cloud::storage::BackoffPolicyOption
: このライブラリはgoogle::cloud::storage::ExponentialBackoffPolicy
クラスを提供します。独自のクラスを指定できますが、その場合、google::cloud::storage::BackoffPolicy
インターフェースを実装する必要があります。google::cloud::storage::IdempotencyPolicyOption
: このライブラリはgoogle::cloud::storage::StrictIdempotencyPolicy
クラスとgoogle::cloud::storage::AlwaysRetryIdempotencyPolicy
クラスを提供します。独自のクラスを指定できますが、その場合、google::cloud::storage::IdempotencyPolicy
インターフェースを実装する必要があります。
詳細については、C++ クライアント ライブラリのリファレンス ドキュメントをご覧ください。
C#
C# クライアント ライブラリで使用されるデフォルトの再試行方法をカスタマイズすることはできません。
Go
ストレージ クライアントを初期化すると、デフォルトの再試行の構成が設定されます。オーバーライドされない限り、構成のオプションはデフォルト値に設定されます。単一のライブラリ呼び出し(BucketHandle.Retryer と ObjectHandle.Retryer を使用)に対して、またはクライアントが行うすべての呼び出し(Client.SetRetry を使用)に対して、デフォルト以外の再試行動作を構成できます。再試行動作を変更するには、該当の RetryOptions をこれらのメソッドのいずれかに渡します。
再試行動作をカスタマイズする方法については、次のコードサンプルをご覧ください。
Java
Storage
を初期化すると、RetrySettings
のインスタンスも初期化されます。オーバーライドされない限り、RetrySettings
のオプションはデフォルト値に設定されます。デフォルトの自動再試行動作を変更するには、Storage
インスタンスの作成に使用する StorageOptions
にカスタム StorageRetryStrategy
を渡します。その他のスカラー パラメータを変更するには、Storage
インスタンスの作成に使用する StorageOptions
にカスタム RetrySettings
を渡します。
再試行動作をカスタマイズする方法については、次の例をご覧ください。
Node.js
Cloud Storage を初期化すると、retryOptions 構成ファイルも初期化されます。オーバーライドされない限り、構成のオプションはデフォルト値に設定されます。デフォルトの再試行動作を変更するには、初期化時にカスタム再試行構成 retryOptions
をストレージ コンストラクタに渡します。Node.js クライアント ライブラリでは、autoRetry
パラメータを使用して、バックオフ方法に沿ったリクエストの再試行を自動的に行えます。
再試行動作をカスタマイズする方法については、次のコードサンプルをご覧ください。
PHP
PHP クライアント ライブラリで使用されるデフォルトの再試行方法をカスタマイズすることはできません。
Python
デフォルトの再試行動作を変更するには、with_XXX
メソッドで呼び出して google.cloud.storage.retry.DEFAULT_RETRY
オブジェクトのコピーを作成します。DEFAULT_RETRY
パラメータを含めると、Python クライアント ライブラリは自動的にバックオフ戦略を使用してリクエストを再試行します。
with_predicate
は、ペイロード データの取得やオブジェクトに送信するオペレーション(アップロードやダウンロードなど)ではサポートされていません。属性は 1 つずつ変更することをおすすめします。詳細については、google-api-core Retry リファレンスをご覧ください。
独自の条件付き再試行を構成するには、ConditionalRetryPolicy
オブジェクトを作成し、カスタム Retry
オブジェクトを DEFAULT_RETRY_IF_GENERATION_SPECIFIED
、DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
、または DEFAULT_RETRY_IF_ETAG_IN_JSON
でラップします。
再試行動作をカスタマイズする方法については、次のコードサンプルをご覧ください。
Ruby
ストレージ クライアントを初期化すると、すべての再試行構成は上記の表にある値に設定されます。デフォルトの再試行動作を変更するには、ストレージ クライアントを初期化中に再試行構成を渡します。
特定のオペレーションの再試行回数をオーバーライドするには、オペレーションの options
パラメータに retries
を渡します。
REST API
指数バックオフ アルゴリズムを使用して、独自の再試行方法を実装します。
指数バックオフ アルゴリズム
指数バックオフのアルゴリズムは、リクエスト間の待ち時間の間隔を最大バックオフ時間まで増加させながら、指数関数的にリクエストを再試行します。通常は、ジッターと指数バックオフを使用して、レスポンスとべき等性の両方の条件を満たすリクエストを再試行する必要があります。指数バックオフを使用して自動再試行を実装するベスト プラクティスについては、カスケード障害への対応をご覧ください。
次のステップ
- リクエストの前提条件の詳細を確認する。