時系列データ用のスキーマ設計

このページでは、時系列データを Bigtable に保存するためのスキーマ設計パターンについて説明します。このページはスキーマの設計に基づいており、このページで説明するコンセプトと推奨事項を十分に理解していることを前提としています。

時系列とは、測定値とその測定値が記録された時刻で構成されるデータの集合です。時系列の例には次のようなものがあります。

  • コンピュータのメモリ使用率のプロット
  • ニュースで報道される温度の経時変化
  • 一定期間における株価

スキーマが適切であれば、高いパフォーマンスとスケーラビリティを得られますが、スキーマが不適切であればパフォーマンスが悪いシステムになることがあります。ただし、すべてのユースケースに最適な、ただ 1 つのスキーマ設計は存在しません。

このページで説明するパターンは、出発点として使用できます。時系列データのスキーマを設計する際に考慮すべき最も重要なことは、独自のデータセットと使用するクエリです。

Bigtable に時系列データを格納するための基本的な設計パターンは次のとおりです。

サンプル用のデータ

パターンごとの違いを説明するために、このページの例では、気象バルーンが 1 分ごとに測定する測定値を記録するアプリのデータを保存する場合を想定します。ここでは、1 つ以上のセルに同時に書き込む単一のリクエストとして、イベントという言葉を使います。ロケーション ID は Google Cloud のリージョンに対応します。

測定
  1. このページのタイムスタンプは、人が読める「tYYYY-MM-DD-HHMM」の形式になっています。本番環境のテーブルでは、タイムスタンプは通常、1970-01-0100:00:00 UTC からのマイクロ秒数で表現されます(例: 1616264288050807)。
圧力(Pa) 94587
温度(摂氏) 9.5
湿度(パーセント) 65
標高(メートル) 601
関連データ
バルーン ID 3698
ロケーション asia-southeast1
タイムスタンプ1 t2021-03-05-1204

時間バケット

時間バケット パターンでは、テーブル内の各行は 1 時間、1 日、1 か月など、時間の「バケット」を表します。行キーには、他の識別データとともに、行に記録された期間の非タイムスタンプ識別子(week49 など)が含まれます。

使用するバケットのサイズ(分、時間、日など)は、使用するクエリと Bigtable のデータサイズ上限によって異なります。たとえば、1 時間のデータを含む行が、1 行あたりの推奨最大サイズである 100 MB より大きい場合、30 分または 1 分を表す行を選ぶ方がおそらく適切です。

時間バケット パターンのメリットは次のとおりです。

  • パフォーマンスが向上します。たとえば、100 個の測定値を保存する場合、これらの測定値が 100 個の行にある場合よりも、1 個の行にある場合のほうが、書き込みと読み取りの速度が向上します。

  • この方法で保存されるデータは、縦長のテーブルに保存されるデータよりも効率的に圧縮されます。

デメリットは次のとおりです。

  • 時間バケット スキーマ設計パターンは、単一タイムスタンプ パターンよりも複雑であるため、開発に多くの時間と労力が必要になる場合があります。

新しいイベントごとに新しい列を追加する

この時間バケット パターンでは、イベントごとに新しい列を行に書き込み、セル値としてではなく、列修飾子にデータを保存します。つまり、セルごとに列ファミリー、列修飾子、タイムスタンプを送信しますが、値は送信しません。

サンプルの気象バルーンデータにこのパターンを使用すると、各行には、単一の気象バルーンの、単一の指標(pressure など)に関する、1 週間にわたるすべての測定値が含まれます。各行キーには、ロケーション、バルーン ID、行に記録する指標、週番号が含まれます。バルーンが指標データを報告するたびに、新しい列を行に追加します。列修飾子には、セルのタイムスタンプで識別できる、1 分間の測定値(Pa 単位の圧力)が含まれます。

この例では、3 分後、行は次のようになります。

行キー 94558 94122 95992
us-west2#3698#pressure#week1 ""(t2021-03-05-1200) ""(t2021-03-05-1201) ""(t2021-03-05-1202)

このパターンのユースケースには次のようなものがあります。

新しいイベントごとに新しいセルを追加する

この時間バケット パターンでは、新しいイベントが作成されるたびに、既存の列に新しいセルを追加します。このパターンでは、Bigtable の機能を利用して、特定の行と列に複数のタイムスタンプ付きセルを保存できます。このパターンを使用する場合は、ガベージ コレクション ルールを指定することが重要です。

たとえば、気象バルーンデータの場合、各行には、1 週間にわたる単一の気象バルーンのすべての測定値が含まれます。行キーの接頭辞は週を識別する識別子であるため、1 回のクエリで複数のバルーンの 1 週間分のデータを読み取れます。他の行キーセグメントは、バルーンが稼働しているロケーションと、バルーンの ID 番号です。テーブルには 1 つの列ファミリー measurements があり、その列ファミリーには、測定のタイプ(pressuretemperaturehumidityaltitude)ごとに 1 つの列があります。

バルーンが測定値を送信するたびに、アプリケーションはバルーンのその週のデータを保持する行に新しい値を書き込み、各列に追加のタイムスタンプ付きセルを書き込みます。週の終わりに、各行の各列には、その週の 1 分ごとの測定値、つまり 10,080 個のセルが書き込まれています(ガベージ コレクション ポリシーで許可されている場合)。

各行の各列には、その週の 1 分ごとの測定値が含まれます。この場合、3 分後、行の最初の 2 列は次のようになります。

行キー 圧力 温度
asia-south2#3698#week1 94558(t2021-03-05-1200) 9.5(t2021-03-05-1200)
94122(t2021-03-05-1201) 9.4(t2021-03-05-1201)
95992(t2021-03-05-1202) 9.2(t2021-03-05-1202)

このパターンのユースケースには次のようなものがあります。

  • 測定値の経時変化を測定する場合。

単一タイムスタンプの行

このパターンでは、既存の行の列にセルを追加する代わりに、新しいイベントまたは測定ごとに行を作成します。行キーの接尾辞はタイムスタンプ値です。このパターンに従うテーブルは縦長になることが多く、行の各列には 1 つのセルしか含まれません。

単一タイムスタンプのシリアル化

このパターンでは、行のすべてのデータを、プロトコル バッファ(protobuf)などのシリアル化された形式で単一の列に保存します。このアプローチの詳細については、スキーマの設計をご覧ください。

たとえば、このパターンを使用して気象バルーンデータを保存する場合、テーブルは 4 分後に次のようになります。

行キー measurements_blob
us-west2#3698#2021-03-05-1200 protobuf_1
us-west2#3698#2021-03-05-1201 protobuf_2
us-west2#3698#2021-03-05-1202 protobuf_3
us-west2#3698#2021-03-05-1203 protobuf_4

このパターンのメリットは次のとおりです。

  • ストレージ効率

  • 速度

デメリットは次のとおりです。

  • データの読み取り時に、特定の列のみを取得できない

  • 読み取り後にデータをシリアル化解除する必要がある

このパターンのユースケースには次のようなものがあります。

  • データのクエリ方法がわからない場合や、クエリが変動する可能性がある場合。

  • 費用を抑える必要性が、Bigtable からデータを取得する前にデータをフィルタリングできる必要性を上回る場合。

  • 各イベントに非常に多くの測定値が含まれていて、データを複数の列に保存すると、行あたり 100 MB の上限を超える可能性がある場合。

単一タイムスタンプのシリアル化解除

このパターンでは、1 つの測定値のみを記録している場合でも、各イベントが固有の行に保存されます。列のデータはシリアル化されません。

このパターンのメリットは次のとおりです。

  • 一般に、時間バケット パターンよりも実装が容易です。

  • スキーマを使用する前のスキーマの改良に費やす時間が少なくなる可能性があります。

このパターンのデメリットは、多くの場合、メリットを上回ります。

  • このパターンでは Bigtable のパフォーマンスは低くなります。

  • この方法で保存されるデータは、幅が広い列に保存されるデータほど効率的に圧縮されません。

  • タイムスタンプが行キーの最後にある場合でも、このパターンでホットスポットが発生する可能性があります。

このパターンのユースケースには次のようなものがあります。

  • すべての列を常に取得し、指定されたタイムスタンプの範囲だけを取得する必要があるが、シリアル化された構造にデータを保存する理由がない場合。

  • 無制限の数のイベントを保存する場合。

気象バルーンのサンプルデータを使用する場合、列ファミリーと列修飾子は、時間バケットと新しいセルを使用する例と同じになります。ただし、このパターンでは、各気象バルーンで報告されたすべての測定値が新しい行に書き込まれます。 次の表に、このパターンで書き込まれる 5 行を示します。

行キー 圧力 温度 湿度 標高
us-west2#3698#2021-03-05-1200 94558 9.6 61 612
us-west2#3698#2021-03-05-1201 94122 9.7 62 611
us-west2#3698#2021-03-05-1202 95992 9.5 58 602
us-west2#3698#2021-03-05-1203 96025 9.5 66 598
us-west2#3698#2021-03-05-1204 96021 9.6 63 624

その他の戦略

同じデータセットで複数の異なるクエリを送信する必要がある場合は、データを複数のテーブルに保存することを検討してください。各テーブルには、各クエリ用に設計された行キーを指定します。

場合によっては、パターンを組み合わせることもできます。たとえば、行が大きくなりすぎる場合を除き、シリアル化されたデータ時間バケットを表す行に保存できます。

次のステップ