Cloud Storage はスケーラビリティに優れたサービスです。自動スケーリング テクノロジーにより、非常に高いリクエスト レートを実現します。このページでは、Cloud Storage のスケーリングとパフォーマンスを改善するためのガイドラインを示します。
自動スケーリング
Cloud Storage はマルチテナント サービスです。つまり、ユーザーは同じ基本リソースセットを共有します。これらの共有リソースを最適に利用するため、バケットの初期の IO 容量は次のように設定されています。
- 1 秒あたり約 1,000 件のオブジェクト書き込みリクエスト。これには、オブジェクトのアップロード、更新、削除が含まれます。Cloud Storage では、同じオブジェクト名に繰り返し書き込む場合にはさらに低い上限が設定されています。
- 1 秒あたり約 5,000 件のオブジェクト読み取りリクエスト。これには、オブジェクト一覧の取得、オブジェクト データの読み取り、オブジェクト メタデータの読み取りが含まれます。
これは、1 MB のオブジェクトについて 1 か月の平均が 2.5 PB の書き込みと 13 PB の読み取りになります。特定のバケットのリクエスト レートが増加すると、Cloud Storage は自動スケーリングを行い、複数のサーバーにリクエストの負荷を分散し、そのバケットの I/O 容量を自動的に増やします。
負荷の再分散に要する時間
バケットの I/O 容量が上限に近くなると、通常 Cloud Storage は数分程度でそれを検知して、より多くのサーバーに負荷を再分散します。ただし、バケットのリクエスト レートの増加が急激で、Cloud Storage での再分散が追いつかない場合、特にレイテンシやエラーレートが一時的に上限に達してしまうことがあります。以下の説明のように、バケットのリクエスト レートを徐々に増やすことで、このようなレイテンシやエラーを回避できます。
オブジェクト キーのインデックス作成
Cloud Storage では整合性のあるオブジェクトの一覧表示をサポートしているため、ユーザーは Cloud Storage に対してデータ処理ワークフローを容易に実行できます。Cloud Storage は、整合性のあるオブジェクトの一覧表示を提供するために、オブジェクト キーのインデックスをバケットごとに保持します。このインデックスは辞書順に並べ替えられて格納され、バケットに対してオブジェクトの書き込みや削除が発生するたびに更新されます。オブジェクトのキーはすべてインデックスの小さな範囲内にあるため、オブジェクトの追加や削除により競合が発生する可能性は必然的に高まります。
Cloud Storage はこのような競合(ホットスポット)を検知し、影響を受けるインデックスの範囲の負荷を複数のサーバーに自動的に再分散します。バケットの I/O 容量のスケーリングと同様に、インデックスの新しい範囲にアクセスするときは(たとえば、新しい接頭辞のもとにオブジェクトを書き込むなど)、以下の説明のように、リクエスト レートを徐々に増やしてください。そうしないと、レイテンシやエラーレートが一時的に高まる可能性があります。
ベスト プラクティス
以下のセクションでは、リクエスト レートを増やす方法、オブジェクト キーを選択する方法、リクエストを分散してバケットの一時的な上限を回避する方法のベスト プラクティスを紹介します。バケットごとの考慮事項に加えて、同じロケーションとプロジェクトのバケットに適用される合計帯域幅制限もあります。
リクエスト レートを徐々に増やす
Cloud Storage の自動スケーリングを常に最適に機能させるためには、高いリクエスト レートが数日間なかったバケットや、オブジェクト キーの新しい範囲を持つバケットのリクエスト レートを徐々に増やす必要があります。毎秒の書き込みリクエストが 1,000 件未満、または読み取りリクエストが 5,000 件未満のリクエスト レートについては、増やす必要はありません。リクエスト レートがこれらのしきい値を超えると予想される場合は、しきい値より低いまたは近いリクエスト レートから徐々にレートを上げていきます。ただし、20 分間でレートが倍にならないようにする必要があります。
レイテンシやエラーレートの増大などの問題が発生した場合は、一時的にリクエスト レートの段階的な増加を中止するか、リクエスト レートを減らして、Cloud Storage でバケットがスケーリングされるまでもうしばらく待ってみます。指数バックオフを使用してリクエストを再試行するのは、次のようなときです。
408
と429
のレスポンス コードでエラーが発生する。5xx
レスポンス コードでエラーが発生する。
階層名前空間が有効になっているバケットでは、階層名前空間が有効になっていないバケットと比較して、オブジェクトの読み取りと書き込みに対する初期の秒間クエリ数(QPS)の制限が最大 8 倍大きくなります。初期 QPS が高いと、データ集約型ワークロードのスケーリングが容易になり、スループットが向上します。バケットで階層名前空間を有効にする方法については、階層名前空間を有効にしてバケットを作成するをご覧ください。
命名規則を使って負荷をキーの範囲に均等に分散する
番号順やタイムスタンプに基づいたオブジェクト キーなど、シーケンシャルな名前を使用している場合、インデックスの範囲の自動スケーリングが遅くなります。これは、リクエストが絶えず新しいインデックスの範囲にシフトするため、負荷の再分散が難しくなり、効果が小さくなるためです。
高いリクエスト レートを維持するためには、シーケンシャルな名前は使用しないでください。完全にランダムなオブジェクト名を使用することで、最適な負荷分散が実現します。シーケンシャルな番号やタイムスタンプをオブジェクト名の一部として使いたい場合は、シーケンシャルな番号やタイムスタンプの前にハッシュ値を追加して、オブジェクト名をランダムなものにします。
たとえば、使用したい元のオブジェクト名が以下の場合:
my-bucket/2016-05-10-12-00-00/file1 my-bucket/2016-05-10-12-00-00/file2 my-bucket/2016-05-10-12-00-01/file3 ...
元のオブジェクト名の MD5 ハッシュを計算し、ハッシュの最初の 6 文字をオブジェクト名の接頭辞として追加します。新しいオブジェクト名は、次のようになります。
my-bucket/2fa764-2016-05-10-12-00-00/file1 my-bucket/5ca42c-2016-05-10-12-00-00/file2 my-bucket/6e9b84-2016-05-10-12-00-01/file3 ...
非常に高い読み取りと書き込みの速度になる場合に、ランダム化されたより長い接頭辞によって、自動スケーリングがより効果的になります。たとえば、ランダムな 16 進数を使用する 1 文字の接頭辞は、接頭辞には 16 個の潜在的な値があるため、最初の 5,000/1,000 回の読み取り / 書き込みから 1 秒あたり約 80,000/16,000 回の読み取り / 書き込みまで、効果的な自動スケーリングを可能にします。ユースケースでこれよりも高いレートが不要な場合は、1 文字のランダムな接頭辞は、2 文字以上の長さのランダムの接頭辞としてリクエスト率を上げる場合とちょうど同じ程度に効果的です。
一般的な接頭辞の後のランダム性はその接頭辞で有効
ランダムな文字列は、必ずしもオブジェクト名の先頭でなくても構いません。一般的な接頭辞の後にランダムな文字列を追加した場合でも自動スケーリングは機能します。ただし、その効果は接頭辞に限定され、バケットの残りの部分は考慮されません。
次に例を示します。
my-bucket/images/animals/4ce4c6af-6d27-4fa3-8a91-5701a8552705/1.jpg my-bucket/images/animals/9a495e72-1d85-4637-a243-cbf3e4a90ae7/2.jpg ... my-bucket/images/landscape/585356ac-ce89-47a8-bdd2-78a86b58fee6/1.jpg my-bucket/images/landscape/2550ae5b-395e-4243-a29b-bbf5aece60ef/2.jpg ... my-bucket/images/clouds/1.jpg my-bucket/images/clouds/2.jpg ...
上の命名では、自動スケーリングは images/animals
、images/landscape,
内のオブジェクトに対して有効に機能しますが、images/clouds
に対しては機能しません。
連続した接頭辞の後のランダム性は効果がない
前述のように、一般的な接頭辞の後にランダムな文字列を追加した場合、その接頭辞でのみ自動スケーリングが機能します。リクエストが新しい接頭辞に移行すると、以前の自動スケーリングは効果がなくなります。これは特に、連続した接頭辞が使用された場合に問題となります。
たとえば、1 時間ごとに新しいタイムスタンプの接頭辞でファイルを書き込む場合、次のようになります。
my-bucket/2016-05-10-00/cf9a7b95-0d2e-4466-9596-840ff388ddbd my-bucket/2016-05-10-00/f1e16a88-16b8-4c66-ba66-a225c87be80c my-bucket/2016-05-10-00/646d8272-4a88-4dc2-b2d4-d537c778df41 ... my-bucket/2016-05-10-01/bdcba6de-ac25-4c27-8550-0d08f249e69d my-bucket/2016-05-10-01/a32c867c-09a9-4d65-9668-ddd4ebe4138b my-bucket/2016-05-10-01/d619485c-5243-4a4e-8ef3-0f7e1d26ce1d ...
自動スケーリングでは、接頭辞に基づく書き込み速度が時間とともに向上しますが、書き込み速度は 1 時間ごとにリセットされます。このため、最適な書き込み速度が得られず、レイテンシとエラー率が定期的に増加します。 時間とともに異なる接頭辞で書き込む必要がある場合は、この問題を回避するため、新しい接頭辞がキー範囲全体に均等に分散されている必要があります。
一括処理の順序を変更して負荷をキーの範囲に均等に分散する
Cloud Storage のデータをまとめてアップロードまたは削除したい場合があります。どちらの場合も、オブジェクト名は制御できませんが、できるだけ高いレートで書き込みや削除が実行されるように、アップロードまたは削除するオブジェクトの順序を制御できます。
そのためには、複数の接頭辞にアップロードや削除を分散する必要があります。たとえば、アップロードする各フォルダの下に多くのフォルダやファイルがある場合は、複数のフォルダから同時にアップロードを行い、アップロードされるフォルダやファイルをランダムに選択することをおすすめします。これにより、キーの範囲全体に負荷が均等に分散されるため、リクエスト レートを最初に増やした後で高いリクエスト レートを実現できます。
次のステップ
- Cloud Storage の割り当てと上限を確認する。
- Cloud Storage へのリクエストで推奨される再試行戦略について学習する。