パフォーマンスについて

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

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

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

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

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

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

Bigtable の容量を計画する

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

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

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

ストレージ使用量とパフォーマンスのトレードオフ

容量計画のもう一つの考慮事項はストレージです。クラスタのストレージ容量は、ストレージ タイプとクラスタ内のノード数によって決まります。クラスタに保存されるデータ量が増加すると、Bigtable はクラスタ内のすべてのノードにデータを分散してストレージを最適化します。

ノードのストレージ使用量は、クラスタのストレージ使用率(バイト数)をクラスタ内のノード数で割ることで計算できます。たとえば、3 つの HDD ノードと 9 TB のデータのあるクラスタについて考えてみましょう。各ノードに格納される容量は約 3 TB です。これは、ノード上限(16 TB)あたりの HDD ストレージの 18.75% に相当します。

ストレージの使用率を高めると、クラスタ全体で CPU のニーズを満たすのに十分なノード数がある場合でも、ワークロードでのクエリ処理のレイテンシが増加する可能性があります。これは、ノードあたりのストレージが大きいほど、インデックス作成などのバックグラウンド処理が必要になるためです。より多くのストレージを処理するためにバックグラウンドの作業が増加すると、レイテンシが増加し、スループットが低下する可能性があります。

レイテンシの影響を受けやすいアプリケーションの場合、ノードあたりのストレージ使用率を 60% 未満にすることをおすすめします。データセットが増加した場合は、ノードを追加して低レイテンシを維持します。

レイテンシの影響を受けにくいアプリケーションの場合、ノードあたりのストレージで説明しているように、上限の 70% を超えて保存できます。

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 クラスタの CPU が過負荷状態のときにノードを追加すると、より多くのノードにワークロードを分散してパフォーマンスを改善できます。
    • ストレージ - ノードあたりのストレージ使用量が推奨値を上回る場合は、クラスタがリクエストを処理するのに十分な CPU を備えていても、最適なレイテンシとスループットを維持するためにノードを追加する必要があります。これは、ノードあたりのストレージを増やすと、ノードあたりのバックグラウンド メンテナンス作業が増えるためです。詳細については、ストレージの使用量とパフォーマンスのトレードオフをご覧ください。
  • 最近 Bigtable クラスタがスケールアップまたはスケールダウンされています。クラスタ内のノード数が増加した後、クラスタのパフォーマンスが大幅に向上するまでに、負荷のかかった状態が最大 20 分間続く可能性があります。Bigtable は、その負荷に基づいてクラスタ内のノードをスケーリングします。

    クラスタ内のノード数を減らしてスケールダウンする場合は、レイテンシの急増を最小限に抑えるため、10 分間は 10% を超えるクラスタサイズの縮小は行わないようにしてください。

  • Bigtable クラスタが HDD ディスクを使用しています。ほとんどの場合、クラスタには SSD ディスクを使用すべきです。SSD ディスクを使用すると、HDD ディスクに比べてパフォーマンスが大幅に向上します。詳しくは、SSD ストレージか HDD ストレージの選択をご覧ください。

  • ネットワーク接続で問題が発生しています。ネットワークの問題が発生するとスループットが低下し、読み取りと書き込みに要する時間が通常より長くなります。特に、クライアントが Bigtable クラスタと同じゾーンで実行されていない場合や、クライアントが Google Cloud の外部で実行されている場合は、問題が発生することがあります。

  • レプリケーションを有効にしていますが、アプリケーションが古いクライアント ライブラリを使用しています。レプリケーションを有効にした後にレイテンシが増加した場合は、アプリケーションで使用している Cloud Bigtable クライアント ライブラリが最新かどうか確認してください。古いバージョンのクライアント ライブラリは、レプリケーションをサポートするように最適化されていない場合があります。Cloud Bigtable クライアント ライブラリで、使用しているクライアント ライブラリの GitHub リポジトリを探してください。ライブラリのバージョンを確認して、必要に応じてアップグレードしてください。

  • レプリケーションを有効にしましたが、クラスタにノードを追加していません。レプリケーションを使用するインスタンスの場合、各クラスタで、アプリケーションからの負荷に加えて、レプリケーションの作業を処理する必要があります。クラスタのプロビジョニングが不足すると、レイテンシが増加する可能性があります。これは、Google Cloud Console のインスタンスの CPU 使用率グラフで確認できます。

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

コールド スタート

Bigtable は、頻繁にアクセスされる大きなテーブルで優れたパフォーマンスを発揮します。このため、一定期間使用されていない状態でリクエストの送信を開始すると、Bigtable が接続を再確立するまでにレイテンシが高くなる可能性があります。

一定期間アクティブでなかった後に Bigtable テーブルにリクエストを送信することがわかっている場合は、接続をウォーム状態で維持し、この高レイテンシを防ぐ次の方法を試すことができます。これらは、QPS が低い期間のパフォーマンスにも役立ちます。

バージョン 2.18.0 より前のバージョンの Java 用 Cloud Bigtable クライアントを使用している場合は、チャネルの更新を有効にすることができます。新しいバージョンでは、チャネル プライミングがデフォルトで有効になっています。

コールド スタートや QPS が低い期間中は、エラーを返すオペレーションの割合よりも Bigtable が返すエラー数のほうが重要になります。

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

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

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

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

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

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

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

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

テーブルへの書き込みが数 GB 未満の場合、Bigtable はすべてのタブレットをクラスタ内の 1 つのノードに保存します。

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

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

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

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

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

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

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

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

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

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

  • ワークロードごとに個別のアプリ プロファイルを使用します。新しいワークロードを追加した後にパフォーマンスの問題が発生した場合は、新しいワークロード用に新しいアプリ プロファイルを作成します。さらに、アプリ プロファイルの指標を個別にモニタリングして、より詳細なトラブルシューティングを行うことができます。複数のアプリ プロファイルの使用が推奨される理由について詳しくは、アプリ プロファイルの仕組みをご覧ください。

  • クライアント サイドの指標を有効にします。クライアント サイドの指標を設定すると、パフォーマンスの問題の最適化とトラブルシューティングに役立ちます。たとえば、Bigtable は均等に分散された高 QPS で最適に機能します。リクエストのごく一部でレイテンシが P100(最大)に増加しても、Bigtable のパフォーマンスの問題が増大するとは限りません。クライアント サイドの指標を使用すると、リクエスト ライフサイクルのどの部分がレイテンシの原因となっているかを把握できます。

次のステップ