Bigtable にデータをエクスポートする(リバース ETL)
このドキュメントでは、BigQuery から Cloud Bigtable へのリバース ETL(RETL)を設定する方法について説明します。これを行うには、EXPORT DATA
ステートメントを使用して、BigQuery テーブルから Bigtable テーブルにデータをエクスポートします。
BigQuery ユーザーは、BigQuery の分析機能と低レイテンシで高スループットの Bigtable を組み合わせて Bigtable への RETL ワークフローを設定できます。このワークフローでは、BigQuery の割り当てと上限を使い切ることなく、アプリケーション ユーザーにデータを配信できます。
Bigtable テーブルの特性
Bigtable テーブルは、いくつかの点で BigQuery テーブルと異なります。
- Bigtable テーブルと BigQuery テーブルはどちらも行で構成されていますが、Bigtable の行は、同じ列ファミリーに属する任意の数の列を持つ行キーと列ファミリーで構成されます。
- 特定のテーブルの列ファミリーはテーブルの作成時に作成されますが、後で追加または削除することもできます。列ファミリーを作成するときに、それに属する列を指定する必要はありません。
- Bigtable の列は事前に定義する必要はありません。テーブルのデータサイズの制限内の名前(修飾子)でデータを保存するために使用できます。
- Bigtable の列には、テーブルのデータサイズの上限内の任意のバイナリ値を設定できます。
- Bigtable の列には、常に時間ディメンション(バージョン)があります。タイムスタンプが同一でない限り、同じ列に任意の数の値を格納できます。
- Bigtable のタイムスタンプは、Unix エポック時刻からのマイクロ秒単位で測定されます。たとえば、0 は 1970-01-01T00:00:00 UTC を表します。タイムスタンプは、ミリ秒単位の粒度で、負ではないマイクロ秒単位にする必要があります(1,000 マイクロ秒の倍数のみを使用できます)。Bigtable のデフォルトのタイムスタンプは 0 です。
- Bigtable 内のデータは、行キー、複数の行キー、行キーの範囲、またはフィルタによって読み取られます。テーブル全体のスキャンを除くどのタイプの読み取りリクエストでも、1 つ以上の行キーまたは行キー範囲が必要です。
Bigtable にエクスポートする BigQuery の結果を準備する方法については、エクスポートするクエリ結果を準備するをご覧ください。
始める前に
このドキュメントの各タスクを実行するために必要な権限をユーザーに与える Identity and Access Management(IAM)のロールを付与します。
必要なロール
BigQuery データを Bigtable にエクスポートするために必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。
- BigQuery テーブルからデータをエクスポートする: BigQuery データ閲覧者(
roles/bigquery.dataViewer
) - エクスポート ジョブを実行する: BigQuery ユーザー (
roles/bigquery.user
) - Bigtable テーブルにデータを書き込む: Bigtable ユーザー(
roles/bigtable.user
)
ロールの付与の詳細については、アクセス権の管理に関する記事をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
制限事項
- エンコードは
BINARY
とTEXT
のみに制限されます。 - BigQuery データセットと同じ場所にある Bigtable クラスタにデータを転送するように、Bigtable アプリ プロファイルを構成する必要があります。詳しくは、ロケーションに関する留意事項をご覧ください。
- Bigtable へのエクスポートは、BigQuery Enterprise エディションまたは Enterprise Plus エディションでのみサポートされています。BigQuery Standard エディションとオンデマンド コンピューティングはサポートされていません。
- Bigtable アプリ プロファイルは、単一クラスタ ルーティングと低優先度で構成する必要があります。
ロケーションに関する留意事項
- BigQuery データセットがマルチリージョンにある場合は、そのマルチリージョン内の Bigtable クラスタにデータを転送するように Bigtable アプリ プロファイルを構成する必要があります。たとえば、BigQuery データセットが
US
マルチリージョンにある場合、Bigtable クラスタは米国内のus-west1
(オレゴン)リージョンに配置できます。 - BigQuery データセットが単一リージョンにある場合は、同じリージョンの Bigtable クラスタにデータを転送するように Bigtable アプリ プロファイルを構成する必要があります。たとえば、BigQuery データセットが
asia-northeast1
(東京)リージョンにある場合、Bigtable クラスタもasia-northeast1
(東京)リージョンに配置する必要があります。
詳細については、Bigtable のロケーションをご覧ください。
サポートされている BigQuery の型
Bigtable に書き込まれるデータの種類は次のとおりです。
BigQuery の型 | 書き込まれる Bigtable の値 |
---|---|
BYTES |
そのままエクスポートされます。 |
STRING |
BYTES に変換されます。 |
INTEGER |
bigtable_options.column_families.encoding が BINARY に設定されている場合、値は 8 バイトのビッグ エンディアン形式(最上位バイトが最初)で書き込まれます。bigtable_options.column_families.encoding が TEXT に設定されている場合、値は数値を表す文字列として人が読める形式で書き込まれます。 |
FLOAT |
IEEE 754 の 8 バイトの出力形式で値を書き込みます。 |
BOOLEAN |
bigtable_options.column_families.encoding が BINARY に設定されている場合、値は 1 バイトの値として書き込まれます(false = 0x00 または true = 0x01)。bigtable_options.column_families.encoding が TEXT に設定されている場合、値はテキスト("true" または "false" )として書き込まれます。 |
JSON |
エクスポートされた
JSON 型の列は、特定の Bigtable 列ファミリーに属する列のグループとして解釈されます。JSON オブジェクトのメンバーは列として解釈され、その値は Bigtable に書き込まれます。書き込まれる列の名前は、bigtable_options 構成で調整できます。 例:
JSON '{"FIELD1": "VALUE1", "FIELD2": "VALUE2"}' as MY_COLUMN_FAMILY ここで、値 VALUE1 と VALUE2 は列 FIELD1 および FIELD2 として Bigtable の列ファミリー MY_COLUMN_FAMILY に書き込まれます。
|
STRUCT |
エクスポートされた
STRUCT 型の列は、特定の Bigtable 列ファミリーに属する列のグループとして解釈されます。構造体のメンバーは列として解釈され、その値は Bigtable に書き込まれます。書き込まれる列の名前は、bigtable_options 構成で調整できます。 例:
STRUCT<FIELD1 STRING, FIELD2 INTEGER> as MY_COLUMN_FAMILY ここで、値 FIELD1 と FIELD2 は列 FIELD1 および FIELD2 として Bigtable の列ファミリー MY_COLUMN_FAMILY に書き込まれます。
|
これらのサポートされるデータ型は、BigQuery の外部 Bigtable テーブルからの読み取りに似ています。
Bigtable 内の NULL
値
Bigtable の NULL
値には次の制約があります。
Bigtable には
NULL
値に類似する値がありません。Bigtable で特定の列ファミリーと列のNULL
値をエクスポートすると、Bigtable の行から現在の値が削除されます。エクスポート前に特定の行キー、列ファミリー、列修飾子、タイムスタンプを持つ Bigtable 値が存在しない場合、エクスポートされた
NULL
値は Bigtable 行に影響しません。STRUCT
型またはJSON
型のNULL
値をエクスポートすると、影響を受ける行が対応する列ファミリーの列値がすべて削除されます。SQL エンジンが適切なタイプに接続できるように、NULL
値をSTRUCT
型またはJSON
型にキャストする必要があります。次のクエリは、指定された行キーのセットを持つ列ファミリーcolumn_family1
からすべてのデータを削除します。EXPORT DATA OPTIONS (...) AS SELECT rowkey, CAST(NULL as STRUCT
) AS column_family1 FROM T 行キーが
NULL
の行はエクスポート時にスキップされます。スキップされた行数は、エクスポート統計情報で呼び出し元に返されます。
bigtable_options
を使用してエクスポートを構成する
エクスポート時に bigtable_options
構成を使用して、BigQuery と Bigtable のストレージ モデルの違いを埋めることができます。構成は、次の例のように JSON 文字列の形式で表現されます。
EXPORT DATA OPTIONS( uri="https://bigtable.googleapis.com/projects/PROJECT_ID
/instances/INSTANCE_ID
/appProfiles/APP_PROFILE_ID
/tables/TABLE
", bigtable_options = """{ "columnFamilies": [{ "familyId": "COLUMN_FAMILY_NAME
", "encoding": "ENCODING_VALUE
", "columns": [ { "qualifierString": "BIGTABLE_COLUMN_QUALIFIER
", ["qualifierEncoded": "BASE_64_ENCODED_VALUE
",] "fieldName": "BIGQUERY_RESULT_FIELD_NAME
" } ] }] }""" )
次の表に、bigtable_options
構成で使用される可能性のあるフィールドを示します。
フィールド名 | 説明 |
---|---|
columnFamilies |
列ファミリー記述子の配列。 |
columnFamilies.familyId |
Bigtable の列ファミリーの識別子。 |
columnFamilies.encoding |
値は BINARY または TEXT に設定できます。型のエンコード方法については、サポートされている BigQuery の型をご覧ください。 |
columnFamilies.columns |
Bigtable の列マッピングの配列。 |
columnFamilies.columns.qualifierString |
省略可: Bigtable の列修飾子。列修飾子に UTF-8 以外のコードがない場合は、この値を指定します。フィールド qualifierString と qualifierEncoding は相互に排他的です。qualifierString と qualifierEncoded のどちらも指定されていない場合は、fieldName が列修飾子として使用されます。 |
columnFamilies.columns.qualifierEncoded |
省略可: Base64 でエンコードされた列修飾子。列修飾子に UTF-8 以外のコードを含める必要がある場合の qualifierString と同様です。 |
columnFamilies.columns.fieldName |
必須: BigQuery 結果セットのフィールド名。状況によっては空の文字列にすることもできます。空の fieldName 値を単純な型のフィールドで使用する方法については、エクスポートするクエリ結果を準備するをご覧ください。 |
エクスポートするクエリ結果を準備する
クエリ結果を Bigtable にエクスポートするには、結果が次の要件を満たしている必要があります。
- 結果セットに
STRING
型またはBYTES
型の列rowkey
が含まれている必要があります。 - 行キー、列修飾子、値、タイムスタンプは、Bigtable のテーブル内のデータサイズの上限を超えないようにする必要があります。
- 結果セットには、
rowkey
以外の列が少なくとも 1 つ必要です。 - 各結果セットの列は、サポートされる BigQuery の型のいずれかである必要があります。サポートされていない列の型は、Bigtable にエクスポートする前に、サポートされている型のいずれかに変換する必要があります。
Bigtable では、有効な BigQuery 列名として列修飾子は必要ありません。また、任意のバイトの使用がサポートされています。エクスポートのターゲット列修飾子をオーバーライドする方法については、bigtable_options
を使用してエクスポートを構成するをご覧ください。
エクスポートされた値を Bigtable API(ReadModifyWriteRow
など)で使用する場合は、数値に正しいバイナリ エンコードを使用する必要があります。
デフォルトでは、STRUCT
または JSON
以外の型のスタンドアロンの結果列は、宛先列ファミリーの値が結果列名に等しく、列修飾子が空の文字列に等しい値として解釈されます。
これらのデータ型がどのように記述されるかを説明するために、次の SQL の例で考えてみましょう。ここで、column
と column2
はスタンドアロンの結果列です。
SELECT
x as column1, y as column2
FROM table
このクエリ例では、JSON
または STRUCT
以外の型を処理するときに、SELECT x as column1
は Bigtable の column1
列ファミリーと ''
(空の文字列)列修飾子の下に値を書き込みます。
次の例に示すように bigtable_options
構成を使用すると、これらの型がエクスポートに書き込まれる方法を変更できます。
EXPORT DATA OPTIONS ( … bigtable_options="""{ "columnFamilies" : [ { "familyId": "ordered_at", "columns": [ {"qualifierString": "order_time", "fieldName": ""} ] } ] }""" ) AS SELECT order_id as rowkey, STRUCT(product, amount) AS sales_info, EXTRACT (MILLISECOND FROM order_timestamp AT TIME ZONE "UTC") AS ordered_at FROM T
この例では、BigQuery テーブル T
に次の行が含まれています。
order_id |
order_timestamp |
product |
amount |
---|---|---|---|
101 | 2023-03-28T10:40:54Z | ジョイスティック | 2 |
上記の bigtable_options
構成をテーブル T
で使用すると、次のデータが Bigtable に書き込まれます。
rowkey |
sales_info (列ファミリー) |
ordered_at (列ファミリー) |
|||
---|---|---|---|---|---|
101 | product | amount | order_time | ||
1970-01-01T00:00:00Z | ジョイスティック | 1970-01-01T00:00:00Z | 2 | 1680000054000 |
1680000054000
は、2023-03-28T10:40:54Z
を UTC タイムゾーンの Unix エポック時刻からのミリ秒単位で表します。
_CHANGE_TIMESTAMP
を使用して行内のすべてのセルにタイムスタンプを設定する
結果に TIMESTAMP
型の _CHANGE_TIMESTAMP
列を追加してエクスポートできます。Bigtable に書き込まれるすべてのセルでは、エクスポートされた結果行の _CHANGE_TIMESTAMP
のタイムスタンプ値が使用されます。
Bigtable は、Unix エポック(1970-01-01T00:00:00Z)より前のタイムスタンプをサポートしていません。_CHANGE_TIMESTAMP
の値が NULL
の場合、デフォルトのタイムスタンプ値として Unix エポック時刻 0
が使用されます。
次のクエリは、テーブル T
の order_timestamp
列で指定されたタイムスタンプを使用して product
列と amount
列のセルを書き込みます。
EXPORT DATA OPTIONS (...) AS SELECT rowkey, STRUCT(product, amount) AS sales_info, order_timestamp as _CHANGE_TIMESTAMP FROM T
同じ rowkey
値を含む複数の結果をエクスポートする
同じ rowkey
値を持つ複数の行を含む結果をエクスポートすると、Bigtable に書き込まれた値は同じ Bigtable 行に格納されます。
この方法を使用すると、同じ行の列値の複数のバージョンを生成できます。この例では、BigQuery の orders
テーブルに次のデータが含まれています。
id |
customer |
order_timestamp |
amount_spent |
---|---|---|---|
100 | Bob | 2023-01-01T10:10:54Z | 10.99 |
101 | Alice | 2023-01-02T12:10:50Z | 102.7 |
102 | Bob | 2023-01-04T15:17:01Z | 11.1 |
次に、ユーザーが次の EXPORT DATA
ステートメントを実行します。
EXPORT DATA OPTIONS (
uri="https://bigtable.googleapis.com/projects/PROJECT-ID/instances/INSTANCE-ID/appProfiles/APP_PROFILE_ID
/tables/TABLE",
format="CLOUD_BIGTABLE"
) AS
SELECT customer as rowkey, STRUCT(amount_spent) as orders_column_family, order_timestamp as _CHANGE_TIMESTAMP
FROM orders
このステートメントを BigQuery orders
テーブルで使用すると、次のデータが Bigtable に書き込まれます。
orders_column_family | ||
---|---|---|
行キー | amount_spent | |
Alice | 2023-01-02T12:10:50Z | 102.7 |
Bob | 2023-01-01T10:10:54Z | 10.99 |
2023-01-04T15:17:01Z | 11.1 |
Bigtable にエクスポートすると、行全体を置き換えるのではなく、新しい値がテーブルにマージされます。Bigtable に行キーの値がすでに存在する場合は、列ファミリー、列名、書き込まれるセルのタイムスタンプに応じて、以前の値を新しい値で部分的または完全にオーバーライドできます。
複数の列をプロトコル バッファ(Protobuf)の値としてエクスポートする
プロトコル バッファは、構造化データをシリアル化するための柔軟で効率的なメカニズムを提供します。Protobuf としてエクスポートすることは、BigQuery と Bigtable の間で異なる型を処理する方法に比べると便利です。BigQuery のユーザー定義関数(UDF)を使用すると、データを Protobuf バイナリ値として Bigtable にエクスポートできます。詳細については、Protobuf 列としてデータをエクスポートするをご覧ください。
エクスポートの最適化
Bigtable 宛先クラスタのノード数を変更すると、BigQuery から Bigtable にレコードをエクスポートする場合のスループットを変更できます。スループット(1 秒あたりに書き込まれる行数)は、宛先クラスタ内のノード数に比例してスケーリングされます。たとえば、宛先クラスタ内のノードの数を 2 倍にすると、エクスポート スループットがほぼ 2 倍になります。
料金
データ エクスポートの料金については、BigQuery の料金ページをご覧ください。
データのエクスポート後、Bigtable にデータを保存すると料金が発生します。詳細については、Bigtable の料金をご覧ください。