[Beta] TiDB ServerlessからクラウドBigQueryに同期する

# はじめに

TiDBからBigQueryなどのクラウドDWHに接続したいというリクエスとは結構聞かれる質問です。
最近、[tidb2dw](https://github.com/pingcap-inc/tidb2dw/tree/main) というツールが登場してこれが手軽に出来るようになりました。
この記事ではTiDB ServerlessからBigQueryへのデータ連係を試して見ようと思います。

:::note warn
2023年12月現在、TiDB ServerlessはCDC機能を提供していないので、差分同期はできません。
スナップショット同期のみになります。
:::

なお、公式blogで[Snowflakeとの連携](https://www.pingcap.com/blog/tidb2dw-replicate-data-to-warehouses/)についても記載があります。

## tidb2dwでBigQueryにデータを同期する

https://github.com/pingcap-inc/tidb2dw/tree/main

tidb2dwは、TiDBから各種クラウドDWHや、s3やgcsといったクラウドストレージへのレプリケーションを行うツールです。データエクスポートには[dumpling]()を、差分同期には[TiCDC]()を利用します。また、TiDB OSSにもTiDB Cloudにも対応しています。

今回TiDB側はお手軽なTiDB Serverlessを利用します。TiDB ServerlessはCDCを提供していないので、スナップショットのみの機能を確認していきます。

### 前準備

TiDB ServerlessからBigQueryにデータを同期させます。この記事では手順を説明しませんが、下記の準備をします。本記事中で利用した値を記載しておきます。

* TiDB側テーブルの準備 - `test.customers`
* Google Cloudでバケットの作成 - `gs://tidb2dwtest`
* BigQueryでデータセットの作成 - `tidb2dw`

### tidb2dwのビルド&インストール

:::note warn
tidb2dwのv0.3ではBigQueryの連携に問題があるため、最新版をビルドします
:::

tidb2dwの最新版をgit cloneして、ビルドします。今回はMacOS上のgolang v1.21で行いました。
```bash
git clone https://github.com/pingcap-inc/tidb2dw.git
cd tidb2dw & make
```
ビルドが成功すると、`bin/tidb2dw` というコマンドができます。以降、このコマンドを利用していきます。

### Google Cloud Application Default Credentialの設定

tidb2dwはBigQueryやGCSのアクセスにGoogle Cloudのクレデンシャルを必要とします。ここでは[ADC(Application Default Credential)](https://cloud.google.com/docs/authentication/provide-credentials-adc)を利用します。
google cloud cliのインストールが必要なので、入っていなければ下記の手順に従ってインストール＆認証まで済ましておきます。

https://cloud.google.com/sdk/docs/install-sdk

```bash
gcloud auth application-default login
```

### 実行

下記のコマンド、オプションで実行します。
```bash 
bin/tidb2dw bigquery --mode snapshot-only \
-h gateway01.ap-northeast-1.prod.aws.tidbcloud.com \
-u <TIDB USER> -p <TIDB PASSWROD> -t test.customers \
--tidb.ssl-ca /etc/ssl/cert.pem \
--bq.project-id <BQ PROJECT NAME> --bq.dataset-id tidb2dw -s gs://tidb2dwtest/
```

利用したオプションは下記です
* bigquery - サブコマンド。対象DWHを指定する。
* mode - 同期モード。今回はsnapshot-onlyを指定。他のオプションはServerlessでは利用できない。
* h - TiDBのホスト名を指定
* u - TiDBのユーザー名を指定
* p - TiDBのパスワードを指定
* t - TiDBのテーブルを指定
* --tidb.ssl-ca - TLSで接続する際のCA証明書を指定。今回はMacOSのものを利用。
* --bq.project-id - BigQueryのプロジェクト名
* --bq.dataset-id - BigQueryのデータセット名
* s - 利用するGoogle Cloud Storageのパス。最後の/も必要です。

内部的にはdumpling出力したテーブル定義とCSVをBigQuery用に変換して、GCSに置き、それをBigQuery側からIMPORTするような動きをしています。ちゃんと出力できたかどうかはGCSを見ると分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/2ade31ba-e413-9d87-6511-5d5e8615aaff.png)

ロードが成功すると、その旨メッセージが出力されます。TiDB ServerlessからデータをExportする際に、いくつかシステムテーブルが出力できないというエラーが出ますが、これはTiDB Serverlessで利用しないシステムテーブルなので無視して構いません。

```bash
[2023/12/16 16:09:42.795 +09:00] [INFO] [snapshot.go:123] ["Loading snapshot data into data warehouse"] [table=test.customers] [path=test.customers.0000000010000.csv]
[2023/12/16 16:09:42.795 +09:00] [INFO] [snapshot.go:123] ["Loading snapshot data into data warehouse"] [table=test.customers] [path=test.customers.000000000.csv]
[2023/12/16 16:09:46.058 +09:00] [INFO] [snapshot.go:128] ["Successfully load snapshot data into data warehouse"] [table=test.customers] [path=test.customers.0000000010000.csv]
[2023/12/16 16:09:46.422 +09:00] [INFO] [snapshot.go:128] ["Successfully load snapshot data into data warehouse"] [table=test.customers] [path=test.customers.000000000.csv]
[2023/12/16 16:09:46.422 +09:00] [INFO] [snapshot.go:148] ["Successfully load all snapshot data into data warehouse"] [table=test.customers] [size=8908] [cost=4.239425417s]
[2023/12/16 16:09:46.871 +09:00] [INFO] [snapshot.go:156] ["Successfully upload loadinfo"] [table=test.customers] [loadinfo="Copy to data warehouse start time: 2023-12-16T16:09:42+09:00\nCopy to data warehouse end time: 2023-12-16T16:09:46+09:00\n"]
```

BigQuery上でもデータが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/781adba3-8562-7e47-bac8-76b1d1ab9e40.png)

## まとめ

data2dwでTiDBからクラウドDWH（最新版ではSnowflake, BigQuery、Redshiftに対応。S3, GCSへの出力も可能）に連携することが可能です。是非利用してください。