Bigtable のパフォーマンスについて

このページでは、最適な条件下にある Cloud Bigtable で実現可能なおおよそのパフォーマンス、パフォーマンスに影響を与える可能性がある要因、Bigtable のパフォーマンスをテストして問題があった場合のトラブルシューティングのヒントを示します。

通常のワークロードでのパフォーマンス

Bigtable では、パフォーマンスを高い精度で予測し、線形的にスケーリングできます。次に説明するパフォーマンス低下の原因を回避した場合、各 Bigtable ノードで実現されるおおよそのスループットは、クラスタで使用されているストレージの種類に応じて次のようになります。

ストレージの種類 読み取り   書き込み   スキャン
SSD 1 秒あたり最大 10,000 行 または 1 秒あたり最大 10,000 行 または 最大 220 MB/秒
HDD 1 秒あたり最大 500 行 または 1 秒あたり最大 10,000 行 または 最大 180 MB/秒

この推定値は、各行に 1 KB のデータが格納されていることを前提としています。

一般に、クラスタにノードを追加すると、クラスタのパフォーマンスは線形的にスケーリングします。たとえば、ノードが 10 個の SSD クラスタを作成すると、通常の読み取り専用または書き込み専用のワークロードの場合、このクラスタでは 1 秒あたり最大 100,000 行をサポートできます。

Bigtable 容量の計画

高スループットと低レイテンシのトレードオフ

Bigtable クラスタを計画する際は、スループットとレイテンシのトレードオフを考慮することが重要です。Bigtable は幅広いアプリケーションで使用されており、ユースケースが異なれば最適化目標も異なります。たとえば、バッチデータ処理ジョブでは、スループットは重視しても、レイテンシはそれほど重視しないことがあります。一方、ユーザー リクエストを処理するオンライン サービスでは、スループットよりもレイテンシの方が優先されることがあります。そのため、目的に応じて容量を計画することが重要です。

一般的なワークロードでのパフォーマンス セクションの数値はスループットを優先する場合は達成できますが、このような負荷での Bigtable のテール レイテンシは、レイテンシの影響を受けやすいアプリケーションには高すぎる可能性があります。Bigtable では一般に、クラスタの CPU 負荷が 70% 未満のとき、最適なレイテンシとなります。レイテンシの影響を受けやすいアプリケーションでは、アプリケーションの最大 Bigtable QPS に対して 2 倍以上の容量を計画することをおすすめします。容量をこのようにすると、Bigtable クラスタは CPU 負荷 50% 未満で動作するため、フロントエンド サービスに対するレイテンシが低くなります。また、クラスタ内のノード間でトラフィックの不均衡が生じる可能性がある、トラフィックの急増やキーアクセス ホットスポットのためのバッファも提供されます。

Bigtable に対して通常のワークロードを実行する

容量の計画を行う際は、Bigtable クラスタに対し、必ず独自の一般的なワークロードを実行してください。これにより、アプリケーションに最適なリソース割り当てを把握できます。

Google の PerfKit Benchmarker は、YCSB を使用してクラウド サービスのベンチマークを行います。Bigtable 用の PerfKitBenchmarker チュートリアルに従って、独自のワークロード用のテストを作成できます。その際は、生成されるベンチマークが本番環境で次の特性を反映するように、ベンチマーク構成 yaml ファイルのパラメータを調整する必要があります。

ベスト プラクティスについては、Bigtable を使ったパフォーマンス テストをご覧ください。

パフォーマンス低下の原因

Bigtable のパフォーマンスが上記の推定値よりも低くなることがあります。その原因として次のことが考えらます。

  • 1 つの読み取りリクエストで連続していない行キーまたは行範囲を大量に読み取る。Bigtable はテーブルをスキャンし、リクエストされた行を順次読み取ります。この並列性の欠如が全体的なレイテンシに影響を与え、ホットノードが読み取られると、テール レイテンシの増加につながる場合があります。詳細については、読み取りとパフォーマンスをご覧ください。
  • テーブルのスキーマが正しく設計されていません。Bigtable で良好なパフォーマンスを得るには、各テーブルに読み取りおよび書き込みを均等に分散できるスキーマを設計することが不可欠です。詳細については、スキーマの設計をご覧ください。
  • Bigtable テーブルの行に大量のデータが含まれています。前述のパフォーマンス推定値は、各行に 1 KB のデータが含まれていることを前提としています。1 行あたり大量のデータを読み取り、書き込みできますが、1 行あたりのデータ量を増やすと、1 秒あたりの行数も減少します。
  • Bigtable テーブルの行に大量のセルが含まれています。Bigtable が行内の各セルを処理するため時間がかかります。セルが多くなると、テーブルにデータを格納する際やネットワーク経由でのデータを送信する際のオーバーヘッドも増加します。たとえば、1 KB(1,024 バイト)のデータを格納する場合、1 バイトずつ 1,024 個のセルに分散させるのではなく、データを 1 つのセルに格納したほうがスペース効率が良くなります。必要以上に多くのセルにデータを分割すると、最高のパフォーマンスが得られない可能性があります。タイムスタンプ付きバージョンのデータが列に複数含まれることで行に多数のセルが含まれている場合は、最新の値のみを保持することを検討してください。既存のテーブルに対する別の方法としては、以前のバージョンすべての削除を書き換えごとに送信することが挙げられます。
  • Bigtable クラスタに十分なノードがない。Bigtable クラスタが過負荷状態になった場合は、ノードを追加するとパフォーマンスが向上します。モニタリング ツールを使用して、クラスタが過負荷状態になっているかどうかチェックしてください。
  • 最近 Bigtable クラスタがスケールアップまたはスケールダウンされています。クラスタ内のノード数を増やしてからスケールアップすると、負荷がかかった状態ではクラスタのパフォーマンスに大幅な改善が見られるまでに最大 20 分を要する場合があります。クラスタ内のノード数を減らしてスケールダウンする場合は、レイテンシの急増を最小限に抑えるため、10 分間は 10% を超えるクラスタサイズの縮小は行わないようにしてください。
  • Bigtable クラスタが HDD ディスクを使用しています。ほとんどの場合、クラスタには SSD ディスクを使用すべきです。SSD ディスクを使用すると、HDD ディスクに比べてパフォーマンスが大幅に向上します。詳しくは、SSD ストレージか HDD ストレージの選択をご覧ください。
  • ネットワーク接続で問題が発生しています。ネットワークの問題が発生するとスループットが低下し、読み取りと書き込みに要する時間が通常より長くなります。特に、クライアントが Bigtable クラスタと同じゾーンで実行されていない場合や、クライアントが Google Cloud の外部で実行されている場合は、問題が発生することがあります。

ワークロードが異なるとパフォーマンスも変化するため、最も正確なベンチマークが得られるよう、テストは自分のワークロードを使って実行してください。

レプリケーションとパフォーマンス

レプリケーションを有効にすると、Bigtable インスタンスのパフォーマンスに影響します。その影響は、一部の指標ではプラスですが、その他の指標ではマイナスになります。レプリケーションの有効化を決定する前に、パフォーマンスに与える可能性のある影響を理解する必要があります。

読み取りスループット

特に複数クラスタ ルーティングを使用する場合は、レプリケーションによって読み取りスループットが向上します。さらに、レプリケーションで、Bigtable データをアプリケーションのユーザーから地理的に近い場所に配置することで、読み取りのレイテンシを短縮できます。

書き込みスループット

レプリケーションによって可用性と読み取りパフォーマンスが向上する可能性はありますが、書き込みスループットは向上しません。1 つのクラスタへの書き込みは、インスタンス内の他のすべてのクラスタに複製される必要があります。したがって、各クラスタは、他のクラスタから変更を pull する目的で CPU リソースを消費します。レプリケーションでは各クラスタが追加の処理を行う必要があるので、実際には書き込みスループットが低下する可能性もあります。

たとえば、単一クラスタ インスタンスがあり、そのクラスタに 3 つのノードがあるとします。

3 つのノードがある単一クラスタ インスタンス

クラスタにノードを追加した場合に書き込みスループットに及ぶ影響は、インスタンスに 3 ノードクラスタをもう 1 つ追加してレプリケーションを有効にする場合とは異なります。

元のクラスタにノードを追加する場合: 3 つのノードをクラスタに追加して、合計 6 つのノードにできます。インスタンスの書き込みスループットは 2 倍になりますが、インスタンスのデータは 1 つのゾーンでのみ利用可能です。

6 つのノードがある単一クラスタ インスタンス

レプリケーションがある場合、あるいは、3 つのノードを持つ 2 番目のクラスタを追加できます(合計 6 つのノード)。インスタンスは、各データを 2 回書き込むようになります。書き込みが最初に受信されたときと、それがもう一方のクラスタに複製されるときです。書き込みスループットは向上せず、低下する可能性もありますが、2 つの異なるゾーンでデータを利用できるというメリットがあります。

6 つのノードがある 2 クラスタ インスタンス

こうした例における単一クラスタ インスタンスでは、複製インスタンスが処理できる 2 倍の書き込みスループットを処理できます(各インスタンスのクラスタに合計 6 つのノードがある場合でも)。

レプリケーション レイテンシ

複数クラスタ ルーティングを使用する場合、Bigtable のレプリケーションは結果整合性があります。一般に、遠距離間でデータを複製するには時間がかかります。異なるリージョンの複製クラスタは、通常、同じリージョンの複製クラスタよりもレプリケーション レイテンシが高くなります。

アプリ プロファイルとトラフィック ルーティング

使用例によっては、Cloud Bigtable トラフィックをルーティングするために 1 つ以上のアプリ プロファイルを使用します。各アプリ プロファイルは、複数のクラスタ ルーティングまたは単一クラスタ ルーティングを使用します。ルーティングの選択はパフォーマンスに影響を与える可能性があります。

複数クラスタ ルーティングは、レイテンシを最小限に抑えることができます。複数クラスタ ルーティングを使用するアプリ プロファイルは、アプリケーションの観点から、インスタンス内の最も近いクラスタに自動的にリクエストをルーティングします。その後、書き込みはインスタンス内の他のクラスタに複製されます。このように最短距離が自動的に選択されるため、レイテンシが可能な限り最小限に抑えられます。

単一クラスタ ルーティングを使用するアプリ プロファイルは、ワークロードの分離や単一クラスタでの read-after-write セマンティクスを使用するなど、特定の使用例には最適ですが、複数クラスタ ルーティングのようにレイテンシを低減することはできません。

こうした使用例に合わせてアプリ プロファイルを構成する方法については、レプリケーション設定の例をご覧ください。

Bigtable が時間の経過とともにデータを最適化する方法

各テーブルの基盤となるデータを格納するために、Bigtable はデータを複数のタブレットに分割します。タブレットは、Bigtable クラスタ内のノード間を移動できます。このストレージ方式により、Bigtable は、2 つの異なる戦略を用いて、時間の経過に伴うデータの最適化を実行できます。

  1. Bigtable は、各 Bigtable ノード上にほぼ同じ量のデータを格納しようと試みます。
  2. Bigtable はすべての Bigtable ノード上に、読み取りオペレーションと書き込みオペレーションを均等に分散しようと試みます。

この 2 つの戦略は互いに矛盾することがあります。たとえば、あるタブレットの行に対する読み取り頻度が非常に高い場合、Bigtable は、一部のノードに格納されるデータが他のノードより多くなったとしても、そのタブレットを専用のノードに格納することがあります。

このプロセスで、Bigtable は、1 つのタブレットを 2 つ以上の小さなタブレットに分割して、タブレット サイズを減らすことや、既存のタブレット内のアクセスが集中している行を分離することがあります。

以下の各セクションで、これらの戦略について詳しく説明します。

各ノードにデータ量を分散配置する

Bigtable テーブルにデータを書き込む際、Bigtable では、テーブルのデータを複数のタブレットに分割します。各タブレットにはテーブル内の連続する範囲の行が格納されます。

テーブルに少量のデータを書き込むと、Bigtable はクラスタ内の単一のノードにすべてのタブレットを格納します。

1 つのノードに 4 つのタブレットが存在するクラスタ。

タブレットが蓄積すると、Bigtable は、その一部をクラスタ内のほかのノードに移動させて、クラスタ全体でデータ量が均等に分散されるようにします。

以降追加されたタブレットは複数のノードに分配される。

各ノードに読み取りオペレーションと書き込みオペレーションを分散させる

スキーマの設計が正しければ、読み取りオペレーションと書き込みオペレーションが表全体にほぼ均等に分散されるはずです。ただし、特定の行に対するアクセス頻度が他の行より高くなるのを避けられないケースもあります。Bigtable は、各ノードにタブレットを分散配置する際に読み取りオペレーションと書き込みオペレーションを考慮することで、このようなケースに対応できるようにします。

たとえば、読み取りオペレーションの 25% がクラスタ内の少数のタブレットに集中しており、それ以外のすべてのタブレットには読み取りオペレーションが均等に分散しているとします。

48 タブレットのうち、25% の読み取りオペレーションが 3 つのタブレットに集中している。

Bigtable は既存のタブレットを再配置して、読み取りオペレーションがクラスタ全体でできる限り均等に分散するようにします。

アクセスが集中している 3 つのタブレットを専用のノードに分離する。

Bigtable を使ったパフォーマンス テスト

Bigtable に依存するアプリケーションのパフォーマンス テストを行う場合は、テストを計画および実行する際に、次のガイドラインに従ってください。

  • 十分なデータでテストする。
    • 本番環境インスタンスのテーブルに含まれるデータがノードあたり合計 100 GB 以下の場合は、同じ量のデータのテーブルでテストします。
    • テーブルに含まれるデータがノードあたり 100 GB を超える場合は、ノードあたり 100 GB 以上のデータを含むテーブルでテストします。たとえば、本番環境のインスタンスに 1 つの 4 ノードクラスタがあり、インスタンスのテーブルに合計 1 TB のデータが含まれている場合は、400 GB 以上のテーブルを使用してテストを実行します。
  • 単一のテーブルでテストする
  • ノードあたりの推奨ストレージ使用率を超えないようにします。詳細については、ノードあたりのストレージ使用率をご覧ください。
  • テスト前に、負荷の大きな事前テストを数分間実行します。この手順により、Bigtable は観察したアクセス パターンに基づいてノード間にデータを分散させます。
  • 最低 10 分間テストを実行します。この手順により、Bigtable はデータをさらに最適化するので、ディスクからの読み取りだけでなく、メモリからのキャッシュ経由の読み取りも確実にテストできます。

パフォーマンスの問題のトラブルシューティング

アプリケーションでパフォーマンスのボトルネックが発生していると思われる場合は、以下のすべての項目をチェックしてください。

  • Key Visualizer でテーブルのスキャン結果を確認します。Bigtable 用 Key Visualizer ツールは、クラスタ内の各テーブルを毎日スキャンし、その使用パターンを表示します。Key Visualizer を使用すると、使用パターンが問題の原因かどうかを確認できます。たとえば、ホットスポットになっている行や CPU の過剰使用を確認できます。こちらで Key Visualizer の使い方をご覧ください。
  • Bigtable の読み取りと書き込みを実行するコードをコメントアウトしてみます。パフォーマンスの問題が解消した場合は、次善のパフォーマンスしか得られないような方法で Bigtable を使用している可能性があります。パフォーマンスの問題が解決しない場合は、おそらく Bigtable とは無関係の問題が発生しています。
  • 作成するクライアント数をできるだけ少なくします。Bigtable でクライアントを作成する処理は比較的負荷の大きいオペレーションです。このため、作成するクライアント数はできるだけ少なくする必要があります。

    • レプリケーションを使用する場合や、アプリ プロファイルを使用してインスタンスへのトラフィックの種類を識別する場合は、アプリ プロファイルごとに 1 つのクライアントを作成し、アプリ全体でそのクライアントを共有します。
    • レプリケーションやアプリ プロファイルを使用しない場合は、クライアントを 1 つだけ作成し、アプリケーション全体で共有します。

    Java 用 HBase クライアントを使用している場合は、クライアントではなく Connection オブジェクトを作成するため、確立する接続の数をできる限り少なくする必要があります。

  • テーブル内で多数の異なる行の読み取りと書き込みが行われていることを確認します。Bigtable では、読み取りオペレーションと書き込みオペレーションがテーブル全体に均等に分散され、結果として、ワークロードがクラスタ内のすべてのノードに分散されるときに、最高のパフォーマンスが得られます。読み取りオペレーションと書き込みオペレーションをすべての Bigtable ノードに分散させることができない場合は、パフォーマンスが低下します。

    読み取りおよび書き込みオペレーションが少数の行に限られていることが判明したら、スキーマの設計を見直して読み取りおよび書き込みオペレーションがより均等に分散されるようにする必要があります。

  • 読み取りオペレーションと書き込みオペレーションで、ほぼ同じパフォーマンスが得られていることを確認します。読み取りオペレーションが書き込みオペレーションに比べてかなり速いことが判明したら、存在しない行キー、またはごく少数の行しか含まれていない広範囲の行キーを読み取ろうとしている可能性があります。

    読み取りオペレーションと書き込みオペレーションの間で正当な比較を行うには、読み取りオペレーションの 90% 以上が有効な結果を返すという状態を目指す必要があります。また、広範な行キーを読み取る場合は、存在する可能性のある最大行数ではなく、その範囲内の実際の行数に基づくパフォーマンスを計測するようにします。

  • データに適したタイプの書き込みリクエストを使用します。データの書き込みに最適な方法を選択すると、高いパフォーマンスを維持できます。

  • 1 行のレイテンシを確認します。ReadRows リクエストの送信時に予期しないレイテンシが発生した場合は、リクエストの最初の行のレイテンシを確認して原因を絞り込むことができます。デフォルトでは、ReadRows リクエストの全体的なレイテンシには、リクエストの各行のレイテンシと、行間の処理時間が含まれます。全体的なレイテンシが高くても、最初の行のレイテンシが低い場合は、Bigtable の問題ではなく、リクエスト数または処理時間がレイテンシの原因であることを意味します。

    Java 用 Cloud Bigtable クライアント ライブラリを使用している場合は、クライアント側の指標を有効にするとCloud Console の Metric Explorerread_rows_first_row_latency 指標を表示できます。

次のステップ