Spanner にデータをエクスポートする(リバース ETL)

この機能に関するフィードバックやサポートのリクエストを行う場合は、bq-cloud-spanner-federation-preview@google.com までご連絡ください。

このドキュメントでは、BigQuery から Spanner への逆方向の抽出、変換、読み込み(リバース ETL)ワークフローを設定する方法について説明します。これを行うには、EXPORT DATA ステートメントを使用して、BigQuery テーブルから Spanner テーブルにデータをエクスポートします。

このリバース ETL ワークフローは、BigQuery の分析機能と Spanner の低レイテンシと高スループットを組み合わせたものです。このワークフローでは、BigQuery の割り当てと上限を使い切ることなく、アプリケーション ユーザーにデータを配信できます。

始める前に

必要なロール

BigQuery データを Spanner にエクスポートするために必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

制限事項

  • 次の BigQuery データ型は Spanner に同等のものがなく、サポートされていません。
Spanner データベース言語 サポートされていない BigQuery の型
すべての言語
  • STRUCT
  • GEOGRAPHY
  • DATETIME
  • RANGE
  • TIME
GoogleSQL
  • BIGNUMERIC: サポートされている NUMERIC 型が十分に広くありません。クエリの NUMERIC 型に明示的なキャストを追加することを検討してください。
  • エクスポートされる行の最大サイズは 1 MiB です。

  • Spanner は、エクスポート中に参照整合性を適用します。ターゲット テーブルが別のテーブルの子テーブルである場合(親にインターリーブされている場合)や、ターゲット テーブルに外部キー制約がある場合、外部キーと親キーはエクスポート中に検証されます。エクスポートされた行が INTERLEAVE IN PARENT を使用してテーブルに書き込まれ、親行が存在しない場合、エクスポートは失敗し、「親行がありません。行を書き込めません」というエラーが表示されます。エクスポートされた行が外部キー制約のあるテーブルに書き込まれ、存在しないキーを参照している場合、エクスポートは失敗し、「外部キー制約に違反しています」というエラーが表示されます。複数のテーブルにエクスポートする場合は、エクスポート中に参照整合性が維持されるように、エクスポートの順序付けを行うことをおすすめします。通常、これは、親テーブルと外部キーで参照されるテーブルを、それらを参照するテーブルの前にエクスポートすることを意味します。

    エクスポートの対象となるテーブルに外部キー制約がある場合、または別のテーブルの子テーブル(親のインターリーブ)である場合は、子テーブルのエクスポートの前に親テーブルにデータを入力し、対応するすべてのキーを含める必要があります。親テーブルに関連するキーの完全なセットがない場合、子テーブルのエクスポートは失敗します。

  • Spanner へのエクスポート ジョブの最大実行時間は 6 時間です。大規模なエクスポート ジョブの最適化については、エクスポートの最適化をご覧ください。または、入力を個々のデータブロックに分割し、個々のエクスポート ジョブとしてエクスポートすることを検討してください。

  • Spanner へのエクスポートは、BigQuery Enterprise エディションまたは Enterprise Plus エディションでのみサポートされています。BigQuery Standard エディションとオンデマンド コンピューティングはサポートされていません。

spanner_options オプションを使用してエクスポートを構成する

spanner_options オプションを使用して、宛先の Spanner データベースとテーブルを指定できます。構成は、次の例に示すように、JSON 文字列の形式で表現されます。

EXPORT DATA OPTIONS(
   uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
   spanner_options = """{
      "table": "TABLE_NAME",
      "priority": "PRIORITY",
      "tag": "TAG",
   }"""
)

次のように置き換えます。

  • PROJECT_ID: Google Cloud プロジェクトの名前。
  • INSTANCE_ID: データベース インスタンスの名前。
  • DATABASE_ID: データベースの名前。
  • TABLE_NAME: 既存の宛先テーブルの名前。
  • PRIORITY(省略可): 書き込みリクエストの優先度。使用できる値: LOWMEDIUMHIGH。デフォルト値: MEDIUM
  • TAG(省略可): Spanner モニタリングでエクスポータ トラフィックを識別するために使用されるリクエストタグ。デフォルト値: bq_export

エクスポート クエリの要件

クエリ結果を Spanner にエクスポートするには、結果が次の要件を満たしている必要があります。

  • 結果セット内のすべての列が宛先テーブルに存在し、型が一致している必要があります。
  • 結果セットには、宛先テーブルのすべての NOT NULL 列が含まれている必要があります。
  • 列の値は、Spanner のテーブル内のデータサイズの上限を超えないようにする必要があります。
  • サポートされていない列の型は、Spanner にエクスポートする前に、サポートされている型のいずれかに変換する必要があります。

データのエクスポート

EXPORT DATA ステートメントを使用して、BigQuery テーブルから Spanner テーブルにデータをエクスポートできます。

次の例では、mydataset.table1 という名前のテーブルから選択したフィールドをエクスポートします。

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
  spanner_options="""{ "table": "TABLE_NAME" }"""
)
AS SELECT * FROM mydataset.table1;

次のように置き換えます。

  • PROJECT_ID: Google Cloud プロジェクトの名前
  • INSTANCE_ID: データベース インスタンスの名前
  • DATABASE_ID: データベースの名前
  • TABLE_NAME: 既存の宛先テーブルの名前

同じ rowkey 値を含む複数の結果をエクスポートする

同じ rowkey 値を持つ複数の行を含む結果をエクスポートすると、Spanner に書き込まれた値は同じ Spanner 行に格納されます。エクスポートによって生成された Spanner 行セットには、一致する BigQuery 行が 1 つだけ存在します(どの行が一致するかは保証されません)。

エクスポートの最適化

BigQuery から Spanner へのレコードのエクスポートを最適化するには、次の方法を試してください。

  • Spanner 宛先インスタンスのノード数を増やす。エクスポートの初期段階では、インスタンス内のノードの数を増やしても、エクスポート スループットがすぐに増加しない場合があります。Spanner が負荷ベースの分割を行うため、若干の遅延が発生することがあります。負荷ベースの分割では、エクスポート スループットが増加し、しばらくすると安定します。書き込みスループットを最大化する方法の詳細については、パフォーマンスの概要をご覧ください。

  • spanner_options 内で HIGH 優先度を指定します。ただし、これを行うと、同じインスタンスで処理される他のワークロードのパフォーマンスが大幅に低下する可能性があります。

  • クエリ結果を並べ替えないでください。結果セットにすべての主キー列が含まれている場合は、エクスポータが宛先テーブルの主キーを自動的に並べ替えて、書き込みを合理化し、競合を最小限に抑えます。

    宛先テーブルの主キーに生成された列が含まれている場合は、生成された列の式をクエリに追加して、エクスポートされたデータが適切に並べ替えられるようにする必要があります。

料金

データ エクスポートの料金の詳細については、BigQuery の料金をご覧ください。

データのエクスポート後、Spanner にデータを保存すると料金が発生します。詳細については、Spanner の料金をご覧ください。