Bigtable の概要

Bigtable はデータがスパース(低密度)に格納されるテーブルで、数十億行、数千列の規模にスケーリング可能です。これにより、数テラバイト、あるいは数ペタバイトのデータを保存できます。各行の単一の値がインデックスに登録され、この値が行キーとなります。Bigtable は、低レイテンシで単一キーの大容量データを保存するために理想的です。低レイテンシで高い読み取り / 書き込みスループットを実現できるため、MapReduce オペレーションに理想的なデータソースです。

Bigtable は、Java 用 Apache HBase ライブラリに対するサポートされた拡張機能など、複数のクライアント ライブラリ経由でアプリケーションに公開されます。このため、オープンソースのビッグデータ ソフトウェアを形成する既存の Apache エコシステムと統合可能です。

Bigtable の強力なバックエンド サーバーには、セルフマネージド HBase インストール環境と比較して、次のような利点があります。

  • 卓越したスケーラビリティ。Bigtable はクラスタ内のマシン台数に正比例してスケールします。セルフマネージド HBase インストール環境には設計上のボトルネックがあるため、しきい値があるレベルに達するとパフォーマンスが制限されます。Bigtable にはこのようなボトルネックはないため、クラスタの規模をスケールして、さらに多くの読み取りおよび書き込みを処理できます。
  • 管理の簡素化。Bigtable はアップグレードを実行し、透過的に再起動されます。また、高いデータ耐久性を自動的に維持します。データを複製する場合、2 番目のクラスタをインスタンスに追加するだけで、複製が自動的に開始されます。レプリカやリージョンを管理する必要はありません。テーブル スキーマさえ設計すれば、他の作業は Bigtable によって処理されます。
  • ダウンタイムなしでクラスタをサイズ変更可能。Bigtable クラスタのサイズを数時間だけ増やして大規模な負荷を処理し、その後、クラスタのサイズを元に戻すことができます。ダウンタイムは一切発生しません。クラスタのサイズを変更すると、クラスタ内の全ノードで均等なパフォーマンスが得られるようになるまで、Bigtable に負荷がかかった状態は通常は数分しかかかりません。

最適な用途

Bigtable は Key-Value データ(それぞれの値のサイズが 10 MB 以下)を扱う、高いスループットとスケーラビリティを必要とするアプリケーションに最適です。また、MapReduce の一括オペレーション、ストリーム処理と分析、機械学習アプリケーションなどのストレージ エンジンとしても優れています。

Bigtable を使用すると、以下のすべてのタイプのデータを格納してクエリできます。

  • 時系列データ。複数のサーバーにおける時間の経過に伴う CPU とメモリの使用状況など。
  • マーケティング データ。購入履歴やお客様の好みなど。
  • 金融データ。取引履歴、株価、外国為替相場など。
  • IoT(モノのインターネット)データ。電力量計と家庭電化製品からの使用状況レポートなど。
  • グラフデータ。ユーザー間の接続状況に関する情報など。

Bigtable ストレージ モデル

Bigtable では、大規模にスケーリング可能なテーブル(並べ替えられた Key-Value マップ)にデータが格納されます。テーブルは、(通常は、各行が単一のエンティティを表す)と(各行の個々の値が格納される)で構成されます。各行は単一の行キーでインデックスに登録されており、相互に関連する列は通常、列ファミリーとしてグループ化されます。各列は列ファミリーと列修飾子(特定の列ファミリー内で一意の名前)の組み合わせによって識別されます。

それぞれの行と列が交差する場所には複数のセルを含めることができます。各セルには、その行と列のデータに付けられた、タイムスタンプ付きの一意のバージョンが格納されます。複数のセルを列に格納すると、その行と列に対して保存されたデータの経時変化を記録できます。Bigtable テーブルはスパースです。つまり、特定の行で使用されていない列が領域を消費することはありません。

Bigtable ストレージ モデル図

この図で注目すべき点を以下に示します。

  • 行内で列が使用されていないことがあります。
  • 特定の行と列のセルごとに固有のタイムスタンプ(t)があります。

Bigtable のアーキテクチャ

以下に、Bigtable 全体のアーキテクチャの概略図を示します。

Bigtable のアーキテクチャ概要。

図のとおり、すべてのクライアント リクエストはフロントエンド サーバーを経由して Bigtable ノードに送信されます(Bigtable のオリジナル論文では、これらのノードを「タブレット サーバー」と呼んでいます)。これらのノードは Bigtable クラスタとして編成されます。Bigtable クラスタは、クラスタのコンテナである Bigtable インスタンスに属しています。

クラスタ内の各ノードは、クラスタに対するリクエストの一部を処理します。クラスタにノードを追加することで、クラスタが同時に処理できるリクエストの数を増やすことができます。ノードを追加すると、クラスタの最大スループットも向上します。クラスタを追加してレプリケーションを有効にする場合は、クラスタごとに異なる種類のトラフィックを送信することもできます。その後、あるクラスタが利用できなくなった場合、別のクラスタにフェイルオーバーできます。

Bigtable テーブルは連続する行ブロック(タブレット)として共有され、クエリの負荷分散を実現します(タブレットは HBase リージョンに相当します)。タブレットは、Google のファイル システムである Colossus に SSTable 形式で格納されます。SSTable は、永続的な順序付きの、キーから値への不変マップとなっています。ここで、キーと値はどちらも任意のバイト文字列です。各タブレットは個々の Bigtable ノードに関連付けられます。すべての書き込みは、SSTable ファイルに格納されるだけでなく、Bigtable に認識されると直ちに Colossus の共有ログにも格納されます。これにより、耐久性が向上します。

重要なことは、データは Bigtable ノード自体に格納されるのではないという点です。各ノードはタブレットのセット(Colossus に格納されている)に対するポインタを保持しています。これにより、以下が実現されます。

  • ノード間のタブレット移動(再調整)が高速になります(実際のデータはコピーされないため)。Bigtable は、各ノードのポインタを更新するだけです。
  • Bigtable ノードの障害復旧が高速に実行されます。これは、置換先の新しいノードにメタデータのみを移動すれば済むためです。
  • Bigtable ノードで障害が発生してもデータが失われることはありません。

これらの基本的な構成要素の処理の方法については、インスタンス、クラスタ、ノードをご覧ください。

負荷分散

各 Bigtable ゾーンはプライマリ プロセスによって管理されます。プライマリ プロセスはクラスタ内の負荷とデータ量の均衡を図ります。このプロセスは、アクセス数の多い大容量のタブレットを半分に分割し、アクセス数の少ない小さなタブレットを結合して、それらのタブレットを必要に応じてノード間で再配置します。特定のタブレットのトラフィックが急増した場合、Bigtable はタブレットを 2 つに分割し、新しいタブレットを別のノードに移動します。Bigtable では、分割、結合、再調整が自動的に管理されるため、タブレットを手動で管理する手間を省くことができます。このプロセスの詳細については、パフォーマンスについてをご覧ください。

Bigtable で最高の書き込みパフォーマンスを実現するには、書き込み操作をノード間でできる限り均等に分散させることが重要です。この目標を達成する方法として、予測可能な順番に従わない行キーを使用する方法があります。たとえば、ユーザー名はアルファベット順でほぼ均等に分散する傾向があるため、ユーザー名を行キーの先頭で使用すると、書き込みの分散が均等になりやすくなります。

また、関連する行をグループ化して、近くにまとまるようにすると便利です。これにより、複数の行を同時に読み取る処理が効率的になります。たとえば、時間の経過に伴いさまざまな種類の天気情報データを格納する場合、データを収集した場所とタイムスタンプを連結したものを行キーとして使用できます(例: WashingtonDC#201803061617)。このような行キーを使用すると、1 つの場所から得られたすべてのデータが、行の連続した範囲としてグループ化されます。他の場所については、行が異なる識別子で始まります。多数の場所で同じ速度でデータが収集されるため、書き込みはタブレット間で均等に分散されます。

データの行キーを正しく選択する方法については、行キーの選択をご覧ください。

サポートされるデータタイプ

Bigtable では、ほとんどの場合、すべてのデータを RAW バイト文字列として扱います。インクリメント演算の場合のみ、Bigtable は型の特定を試みます。インクリメント演算では、ターゲットは、8 バイトのビッグエンディアン値としてエンコードされた 64 ビットの整数である必要があります。

メモリとディスクの使用状況

以下の各セクションでは、Bigtable のいくつかのコンポーネントが、インスタンスでのメモリとディスクの使用状況にどのような影響を与えるのかについて説明します。

未使用の列

Bigtable の行で使用されていない列は、その行内の領域を消費しません。各行は基本的に Key-Value エントリの集合です。キーとは、列ファミリー、列修飾子、タイムスタンプを連結したものです。行に特定の列の値が含まれていない場合、その Key-Value エントリは存在しないものとみなされます。

列修飾子

列修飾子は行内で領域を消費します。行で使用される各列修飾子はその行に格納されるためです。そのため、列修飾子をデータとして使用すると効率的なことがよくあります。

コンパクション

Bigtable は定期的にテーブルをリライトして削除されたエントリを除去し、読み取りと書き込みの処理効率が向上するようにデータを再編成します。このプロセスはコンパクションと呼ばれます。コンパクションの構成設定はなく、Bigtable がデータを自動的に圧縮します。

ミューテーションと削除

行に対するミューテーション、すなわち変更を行うと、ストレージ領域が余分に消費されます。これは、Bigtable ではミューテーションは順次格納され、圧縮は定期的にしか行われないためです。Bigtable がテーブルを圧縮すると、不要になった値が削除されます。セルの値を更新すると、元の値と新規の値の両方がディスク上に保管され、一定期間が経過するとデータが圧縮されます。

削除した場合も、少なくとも短期間は余分な領域が消費されます。削除は実際には特殊なタイプの mutation だからです。テーブルが圧縮されるまで、この余分な領域は解放されず、消費されたままになります。

データ圧縮

Bigtable は、インテリジェントなアルゴリズムを使用してデータを自動的に圧縮します。テーブルの圧縮設定を構成することはできません。ただし、効率的に圧縮されるようにデータを格納する方法を知っておくことは有益です。

  • ランダムデータはパターン化されたデータよりも圧縮効率が低くなります。パターン化されたデータの例として、テキスト(たとえば、皆さんが今ご覧になっているこのページ)があります。
  • 圧縮は、同じ値が互いに近接した場所にある場合に、処理の効率が最も高くなります。近接した場所とは、同一行または隣接する行のことです。同じデータチャンクが格納された行が互いに隣接するように行キーを調整すれば、データを効率的に圧縮できます。
  • Bigtable は、最大 1 MiB のサイズの値を圧縮します。1 MiB を超える値を保存する場合は、Bigtable に書き込む前に値を圧縮して、CPU サイクル、サーバーメモリ、ネットワーク帯域幅を節約します。

データの耐久性

Bigtable を使用すると、データが Colossus 上に格納されます。Colossus は、Google 内部の高い耐久性を持つファイル システムで、Google データセンター内のストレージ デバイスを使用して構築されています。Bigtable を使用するために、HDFS クラスタ、またはその他のファイル システムを稼働する必要はありません。背後で、Google が独自のストレージ方式を使用して、標準の HDFS 3 方向レプリケーションによって提供されている以上のデータの耐久性を実現しています。

レプリケーション使用時の耐久性がさらに向上します。Bigtable では、レプリケートされたインスタンスのクラスタごとに選択したロケーションに、データのコピーが個別に保持されます。

整合性モデル

単一クラスタの Bigtable インスタンスでは、強整合性を実現しています。デフォルトでは、複数のクラスタを持つインスタンスは結果整合性を提供しますが、一部のユースケースでは、ワークロードとアプリ プロファイルの設定に応じて、書き込み後読み取りの整合性または強整合性を提供するように構成できます。

セキュリティ

Bigtable テーブルへのアクセスは、Google Cloud プロジェクトと、ユーザーに割り当てる Identity and Access Management(IAM)ロールによって制御されます。たとえば、各々のユーザーがテーブルからの読み取り、テーブルへの書き込み、新しいインスタンスの作成を実行できないようにする IAM ロールを割り当てることができます。プロジェクトへのアクセス権を持たないユーザーや、Bigtable に適切な権限がある IAM ロールを持たないユーザーは、どのテーブルにもアクセスできません。

プロジェクト、インスタンス、テーブルの各レベルでセキュリティを管理できます。Bigtable では、行レベル、列レベル、セルレベルでのセキュリティ制限をサポートしていません。

暗号化

デフォルトでは、Bigtable テーブルのデータを含め、Google Cloud 内に保存されているすべてのデータは、独自の暗号化データに使用しているものと同じ強化されたキー管理システムを使用して、保存時に暗号化されます。

保存中の Bigtable データの暗号化に使用される鍵をより細かく制御するには、顧客管理の暗号鍵(CMEK)を使用できます。

バックアップ

Bigtable バックアップを使用すると、テーブルのスキーマとデータのコピーを保存して、後で新しいテーブルに復元できます。バックアップとバックアップのコピーを使用すると、ソーステーブルの場所に関係なく、Bigtable インスタンスがあるリージョンまたはプロジェクトの新しいテーブルに復元できます。

変更データ キャプチャ

Bigtable では、変更データ キャプチャ(CDC)を変更ストリームの形式で実現します。変更ストリームを使用すると、変更の発生時にデータ変更を取得し、テーブルにストリーミングできます。Dataflow などのサービスを使用して変更ストリームを読み取ることで、データ分析、監査、アーカイブ要件、ダウンストリーム アプリケーション ロジックのトリガーなどのユースケースをサポートできます。詳細については、変更ストリームの概要をご覧ください。

アプリ プロファイルを使用してルーティングをリクエストする

アプリ プロファイルのルーティング ポリシーを使用すると、アプリケーションからの受信リクエストを処理するクラスタを制御できます。ルーティング ポリシーのオプションは次のとおりです。

  • 単一クラスタ ルーティング: すべてのリクエストを単一クラスタに送信します。
  • 任意のクラスタへのマルチクラスタ ルーティング: インスタンス内で最も近い使用可能なクラスタにリクエストを送信します。
  • クラスタ グループのルーティング: インスタンスに選択されたクラスタ グループ内で最も近い使用可能なクラスタにリクエストを送信します。

ストレージとデータベースに関するその他のオプション

Bigtable はリレーショナル データベースではありません。したがって、SQL クエリ、結合、複数行トランザクションはサポートしていません。

  • オンライン トランザクション処理(OLTP)システム用の完全な SQL サポートが必要な場合は、Spanner または Cloud SQL を検討してください。
  • オンライン分析処理(OLAP)システムでのインタラクティブなクエリが必要な場合は、BigQuery を検討してください。
  • ドキュメント データベースで高度に構造化されたオブジェクトを格納する必要があり、さらに ACID トランザクションや SQL ライクなクエリのサポートが必要な場合は、Firestore を検討してください。
  • インメモリ データ ストレージが低レイテンシである場合は、Memorystore を検討してください。
  • ユーザー間でリアルタイムにデータを同期する場合は、Firebase Realtime Database を検討してください。

他のデータベース オプションについて詳しくは、データベース サービスの概要をご覧ください。Google Cloud にも、さまざまなストレージ オプションが用意されています。

次のステップ