RDS for MySQL で Redshift との Zero-ETL 統合（プレビュー）を試してみた

これは **[MySQL Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mysql)** の 20 日目の記事です。

昨日（19 日）は tom--bo さんでした。

- **[InnoDB redo logを解読している話](https://tombo2.hatenablog.com/entry/2023/12/19/033704)**

https://tombo2.hatenablog.com/entry/2023/12/19/033704

---

以前、[GA 前の Aurora MySQL で Redshift との Zero-ETL 統合を試しました](https://zenn.dev/hmatsu47/articles/aurora-rs-zeroetl-preview) が、re:Invent 2023 期間中に RDS for MySQL との zero-ETL 統合もプレビュー公開されましたので、同じように試してみました。

https://zenn.dev/hmatsu47/articles/aurora-rs-zeroetl-preview

:::note warn
この記事は 2023/12/13 現在の情報をもとに構成しています。
:::

## Zero-ETL 統合についておさらい

ざっくりいうと **細かい ETL の設定なしにデータウェアハウスや分析基盤などにデータを流す機能** です。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.html

[以前の記事](https://zenn.dev/hmatsu47/articles/aurora-rs-zeroetl-preview)での説明は以下のとおりです。

> Aurora などのリレーショナルデータベース上のデータは、通常 ETL（Extract（抽出）/ Transform（変換）/ Load（ロード）の略）の流れを経て Redshift などのデータウェアハウスや分析基盤への流し込みを行います。
>
> Aurora と Redshift のゼロ ETL 統合は、 **この部分の構築・設定を簡素化し、ほぼリアルタイムでデータの流し込み（複製）を可能にする機能** です。
>
> 結果として、Redshift を使用した分析や機械学習がほぼリアルタイムで実行できます。

今回は Aurora ではなく RDS for MySQL で試します。

:::note
Aurora PostgreSQL も同時にプレビュー公開されています（オハイオリージョン限定）。
:::

## 手順

ほぼ Aurora MySQL のときと同じですが、不可解なエラーで設定が詰まることはありませんでした。

:::note warn
ただし、試用中に一つだけ大きな問題が発生しました（後述）。
:::

### 1. DB パラメータグループ作成

[ユーザーガイドの指示](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.setting-up.html#zero-etl.parameters)どおりに設定します。

- `binlog_format=ROW`
- `binlog_row_image=full`
- `binlog_checksum=NONE`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/df9484e4-0728-537b-fc44-7b1e354f1bd2.png)

:::note
`innodb_redo_log_capacity`はデフォルト値のまま未変更です。
:::

### 2. ソース DB（RDS for MySQL）作成

RDS for MySQL 8.0.28 以降の DB インスタンスを作成します。

- MySQL Community Edition
- エンジンバージョン : 8.0.35
- テンプレート : 開発 / テスト用（単一のインスタンス）
- DB インスタンス識別子 : 任意（今回は初期値`database-1`のまま作成）
- AWS Secrets Manager でマスター認証情報を管理しない
- DB インスタンスクラス : 今回は db.t4.small を選択
- ストレージ : 今回は gp3 20GiB（最低容量）
- コンピューティングリソース : EC2 コンピューティングリソースに接続しない
- ネットワークタイプ : 今回は IPv4
- VPC / DB サブネットグループ : 任意
- パブリックアクセス : なし
- VPC セキュリティグループ : 作業用の EC2 や Zero-ETL 統合先の Redshift に接続できるように設定したものを選択
- データベース認証 : 今回は「パスワード認証」のまま
- DB パラメータグループ : 1. で設定したものを指定
- 自動バックアップを有効化
- バックアップ保持期間 : 最低 1 日間
- 暗号化 : 今回はデフォルトのキーで有効化

### 3. ターゲット Redshift データウェアハウスを作成（Redshift Serverless プレビュー版ワークグループ）

Aurora MySQL のときと同様に画面右上の「Create preview workgroup」から Redshift Serverless のプレビュー版を作成します。

- ワークグループ名 : 任意（今回は`zeroetl-workgroup`）
- Performance and cost controls : ベース RPU 容量を選択（容量は 128）
- ネットワークとセキュリティ : RDS インスタンスに接続可能な VPC・セキュリティグループ・サブネットを指定
- 名前空間 : 新しい名前空間を作成（今回は`zeroetl-namespace`）
- 許可 : 「デフォルトを設定」から新規に作成（ロールがアクセスする S3 バケットに「任意の S3 バケット」を指定）
- 作成したロールを選択（チェック）して関連付け
- ログはひととおりチェックを入れて出力対象に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/8b60e503-e833-87af-70a5-1853ad02ea92.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/191884a1-3a7d-4849-91a0-fb69920efaa0.png)

作成したら[ユーザーガイドの **Enable case sensitivity on the data warehouse**](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.setting-up.html#zero-etl.create-cluster) のとおりに CloudShell から大文字・小文字の識別を有効化します。

```sh:大文字・小文字の識別有効化
aws redshift-serverless update-workgroup \
  --workgroup-name zeroetl-workgroup \
  --config-parameters parameterKey=enable_case_sensitive_identifier,parameterValue=true
```

そして名前空間の **Authorized principals** と **Authorized integration sources** を設定します（それぞれ右上の「Add…」ボタンから）。

- Authorized principals : アカウント ID を指定
- Authorized integration sources : ソース DB の ARN を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/5d57065d-2735-cc9d-3695-6ca9607d6363.png)

### 4. Zero-ETL 統合を作成

まず[ユーザーガイドのこちらの **Sample policy**](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.creating.html#zero-etl.create-permissions) を参考に IAM でポリシーを作成します。

そのポリシーを持つ IAM ロールを作成し、先ほどの名前空間の **Authorized principals** に追加します。

:::note
この工程（IAM ロール作成・追加）は不要かもしれません。
:::

[ユーザーガイド](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.creating.html#zero-etl.create)を参考に、DB インスタンスの「ゼロの ETL 統合」タブから Zero-ETL 統合を作成します。

- 統合名 : 任意（今回は`zeroetl`）
- ソースデータベース : 2. で作成した DB
- Data warehouses : 先ほど作成した名前空間（`zeroetl-namespace`）
  - ここでポリシーの権限が足りない場合は↓のような警告が表示され、「Fix it for me」をチェックすると修正内容の確認が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/a69da5be-ae34-5322-88f9-3e9700690c12.png)

確認して作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/b53470f8-6aaf-f1d2-8d84-8051b77a7e07.png)

しばらく（初回は 30 分前後かそれ以上）待つと Zero-ETL 統合の Status が Active になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/bbd55da1-faaa-6c78-d821-93f47f9f7964.png)

データウェアハウスのデータベースが作成されていないので、Zero-ETL 統合の画面から「Create database from integration」ボタンをクリックして作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/1e618148-f3b9-b99d-fadd-9fb3f59e423a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/efb6e1bb-48f3-58bd-47d2-c78f22ff565b.png)

再びしばらく待つとデータウェアハウスのデータベースが作成されてデータがロードされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/f7c4603c-6027-848c-ba78-0121a71c34da.png)
このあたりは [Aurora MySQL の Zero-ETL プレビュー版の頃](https://zenn.dev/hmatsu47/articles/aurora-rs-zeroetl-preview#%E3%82%BC%E3%83%AD-etl-%E7%B5%B1%E5%90%88%E4%BD%9C%E6%88%90)と比べて安定していますね。

Redshift query editor v2 からクエリを実行すると結果が返ってきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/b54d5204-1096-be8b-7742-e4046e693ac4.png)

## 注意点

私が実際に試したときには、以下のような不具合が発生しました。

- ソース DB を一時的に停止してその後再開すると、ソース DB での追加・更新・削除がターゲットのデータウェアハウスに一切反映されなくなる

[ユーザーガイドの **General limitations**](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.html#zero-etl.reqs-lims) には、

> - If you stop the source DB instance, the last few transactions might not be replicated to the target data warehouse until you resume the instance.
> - You can’t delete an integration if the source DB instance is stopped.

とだけ書いてあるので、ソース DB を停止してはいけない仕様ではないはずです。

このときは結局 Zero-ETL 統合を作り直しました。

また、Aurora MySQL の Zero-ETL 統合は GA になりましたが、制約のうち「列フィルタが使えない」点については GA でもそのままです。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/zero-etl.html#zero-etl.reqs-lims

> - Zero-ETL integrations don’t currently support data filtering.

MySQL から Redshift へ変換できる列の型の範囲が限定されているため、例えば`BLOB`型の列を持つテーブルは Redshift にそのままデータ連携できません。

そのため、プロダクト利用しているデータベースのテーブルをそのまま Zero-ETL 統合で連携するには少し厳しいのではないか？と思います。

レプリケーションチャネルフィルタの利用も非推奨のようなので、対象テーブルの除外も自己責任になりますし。

> - Zero-ETL integrations rely on MySQL binary logging (binlog) to capture ongoing data changes. We recommend that you do not use binlog-based data filtering, as it can cause data inconsistencies between the source and target databases.

## おまけ

[先日（12/18）の JAWS-UG 名古屋](https://jawsug-nagoya.doorkeeper.jp/events/165969)でも少し触れました。

https://www.docswell.com/s/hmatsu47/ZGX4PM-2023-12-17-160927#p10

Aurora MySQL で Redshift との Zero-ETL 統合を使うには enhanced binary log の設定が必須、Aurora PostgreSQL（プレビュー）でも enhanced logical replication という（初めて見た）設定が必須になっています。

いずれもコンピュート層を介さずストレージ層で Redshift にデータ転送ができるようです（enhanced logical replication については「IOPS の向上」以外に記述が見当たらないので推測ですが）。

一方で RDS for MySQL の場合は Optimized Writes などは必須ではなく、Zero-ETL 統合作成時と非作成時でパフォーマンスに差がなさそうだったので（いずれも binary log 生成のためのオーバーヘッドのみ発生？）、どこで binary log を読み取ってデータ転送をしているのかは不明です。

---

明日（21 日）は mita2 さんです。

- **[MySQL Shell dumpInstance の分割ロジック その1](https://mita2db.hateblo.jp/entry/dumpshellchunk1)**

https://mita2db.hateblo.jp/entry/dumpshellchunk1