MaxCompute は、Flink CDC と連携するための新しいバージョンのコネクタを提供します。このコネクタを使用すると、ソース (MySQL など) のデータを MaxCompute のターゲットテーブル (通常テーブルまたは Delta テーブル) にリアルタイムで同期できます。本記事では、MaxCompute の新しいプラグインの機能と主な操作手順について説明します。
Flink CDC の背景
Flink CDC は、エンドツーエンドのオープンソースリアルタイムデータ統合ツールで、機能的に完全なプログラミングインターフェースと ETL データ処理フレームワークを定義しています。ユーザーは Flink ジョブを送信することでその機能を使用できます。詳細については、「Flink CDC」をご参照ください。Flink CDC は Apache Flink と深く統合され、それによって駆動されることで、以下の主な機能を提供します。
-
エンドツーエンドのデータ統合フレームワーク。
-
データ統合ユーザー向けのジョブ構築が容易な API。
-
ソースとシンクにおける複数テーブルの処理のサポート。
-
データベース全体の同期。
-
スキーマエボリューション (テーブル構造変更の自動同期)。
前提条件
MaxCompute プロジェクトが作成済みであること。詳細については、「MaxComputeプロジェクトの作成」をご参照ください。
注意事項
-
データ同期コネクタは、自動テーブル作成をサポートしており、MaxCompute テーブルとソーステーブルの位置関係、データ型を自動的にマッピングします。ソーステーブルにプライマリキーがある場合は自動的に Delta テーブルが作成され、そうでない場合は MaxCompute の通常テーブルが作成されます。マッピングの詳細については、「テーブル位置のマッピング」および「データ型マッピング」をご参照ください。
-
データを通常テーブルに書き込む場合、システムは
DELETE操作を無視し、UPDATE操作はINSERT操作として扱われます。 -
現在、at-least-once のみをサポートしています。Delta テーブルはプライマリキーの特性により、べき等な書き込みを実現できます。
-
テーブル構造変更の同期について。
-
列は、最後の列としてのみ追加可能です。
-
列の型を変更する場合、互換性のあるデータ型にのみ変更できます。データ型の互換性の詳細については、「ALTER TABLE」をご参照ください。
クイックスタート
本記事では、Flink CDC に基づいて、MySQL から MaxCompute への Streaming ETL ジョブ (MySQL to MaxCompute) を迅速に構築し、Flink CDC パイプラインを作成する方法を説明します。これには、データベース全体の同期、テーブル構造変更の同期、およびシャーディングされたデータベースとテーブルの同期機能が含まれます。
事前準備
Flink スタンドアロンクラスターの準備
-
flink-1.18.0-bin-scala_2.12.tgz をダウンロードして解凍します。解凍後、
flink-1.18.0ディレクトリが生成されます。flink-1.18.0ディレクトリに移動し、次のコマンドを実行して FLINK_HOME を flink-1.18.0 のインストールディレクトリに設定します。export FLINK_HOME=$(pwd) -
$flink-1.18.0/confディレクトリでvim flink-conf.yamlコマンドを実行し、設定ファイルに以下のパラメーターを追加して保存します。# チェックポイントを有効にし、3秒ごとにチェックポイントを作成します # テスト目的でのみ使用します。実際のジョブでは、チェックポイントの間隔を30秒未満にしないことを推奨します execution.checkpointing.interval: 3000 # flink-cdc-pipeline-connector-maxcomputeはFlinkの通信メカニズムに依存して書き込みを同期するため、 # ここではメッセージ通信のタイムアウト時間を適切に増やします pekko.ask.timeout: 60s -
次のコマンドを実行して Flink クラスターを起動します。
./bin/start-cluster.sh起動に成功すると、http://localhost:8081/ (8081 はデフォルトポート) で Flink Web UI にアクセスできます。
start-cluster.sh を複数回実行すると、複数の TaskManager を起動して並列実行できます。
MySQL 環境の準備
ここでは Docker Compose を使用した MySQL 環境の準備方法を例に説明します。
-
Docker イメージを起動後、
docker-compose.yamlという名前のファイルを作成し、以下の内容を記述します。version: '2.1' services: mysql: image: debezium/example-mysql:1.1 ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_USER=mysqluser - MYSQL_PASSWORD=mysqlpwパラメーターの説明:
パラメーター
説明
version
Docker Compose ファイルのバージョン。
image
イメージのバージョン。debezium/example-mysql:1.1 に設定します。
ports
MySQL のポート番号。
environment
MySQL のアカウントとパスワード。
この Docker Compose には、商品情報を含むデータベース app_db を持つ MySQL コンテナが含まれています。
-
docker-compose.yaml のあるディレクトリで次のコマンドを実行し、必要なコンポーネントを起動します。
docker-compose up -dこのコマンドは、Docker Compose 設定ファイルに定義されているすべてのコンテナをデタッチモードで自動的に起動します。
docker psコマンドを実行して、上記のコンテナが正常に起動しているかを確認できます。
MySQL データベースでのデータ準備
-
次のコマンドを実行して MySQL コンテナに入ります。
docker-compose exec mysql mysql -uroot -p123456 -
MySQL でデータベースを作成し、テーブルデータを準備します。
-
データベースを作成します。
CREATE DATABASE app_db; USE app_db; -
テーブルデータを準備します。
-
orders テーブルを作成し、データを挿入します。
CREATE TABLE `orders` ( `id` INT NOT NULL, `price` DECIMAL(10,2) NOT NULL, PRIMARY KEY (`id`) ); -- データを挿入 INSERT INTO `orders` (`id`, `price`) VALUES (1, 4.00); INSERT INTO `orders` (`id`, `price`) VALUES (2, 100.00); -
shipments テーブルを作成し、データを挿入します。
CREATE TABLE `shipments` ( `id` INT NOT NULL, `city` VARCHAR(255) NOT NULL, PRIMARY KEY (`id`) ); -- データを挿入 INSERT INTO `shipments` (`id`, `city`) VALUES (1, 'beijing'); INSERT INTO `shipments` (`id`, `city`) VALUES (2, 'xian'); -
products テーブルを作成し、データを挿入します。
-- CREATE TABLE `products` ( `id` INT NOT NULL, `product` VARCHAR(255) NOT NULL, PRIMARY KEY (`id`) ); -- データを挿入 INSERT INTO `products` (`id`, `product`) VALUES (1, 'Beer'); INSERT INTO `products` (`id`, `product`) VALUES (2, 'Cap'); INSERT INTO `products` (`id`, `product`) VALUES (3, 'Peanut');
-
-
Flink CDC CLI を介したジョブの送信
-
必要な JAR パッケージをダウンロードします。
-
flink-cdc パッケージ
flink-cdc にアクセスして、バイナリ圧縮パッケージ flink-cdc-3.1.1-bin.tar.gz をダウンロードし、解凍すると
flink-cdc-3.1.1ディレクトリが展開されます。このディレクトリには bin、lib、log、conf の 4 つのディレクトリが含まれています。これらのディレクトリ内のファイルを flink-1.18.0 の対応するディレクトリに移動します。 -
コネクタパッケージ
以下のコネクタパッケージをダウンロードし、
flink-1.18.0/libディレクトリに移動します。説明ダウンロードリンクは、リリース済みのバージョンにのみ有効です。SNAPSHOT バージョンは、ローカルで master または release- ブランチを基にコンパイルする必要があります。
-
ドライバーパッケージ
MySQL Connector/J パッケージをダウンロードし、--jar パラメーターを使用して Flink CDC CLI に渡すか、
$flink-1.18.0/libディレクトリに配置して Flink クラスターを再起動します。これは、CDC Connectors にこれらのドライバーが含まれなくなったためです。
-
-
ジョブ設定の YAML ファイルを作成します。以下に、データベース全体の同期を行うサンプルファイル
mysql-to-maxcompute.yamlを示します。################################################################################ # 説明: MySQLのすべてのテーブルをMaxComputeに同期します ################################################################################ source: type: mysql hostname: localhost port: 3306 username: root password: 123456 tables: app_db.\.* server-id: 5400-5404 server-time-zone: UTC # accessId、accessKey、endpoint、projectはユーザー自身で入力する必要があります sink: type: maxcompute name: MaxComputeSink accessId: ${your_accessId} accessKey: ${your_accessKey} endpoint: ${your_maxcompute_endpoint} project: ${your_project} bucketsNum: 8 pipeline: name: Sync MySQL Database to MaxCompute parallelism: 1パラメーターの説明:
-
Source 部分のパラメーター設定の詳細については、「Apache Flink CDC MySQL Connector」をご参照ください。
-
Sink 部分のパラメーター設定については、「コネクタの設定項目」をご参照ください。
-
-
次のコマンドを実行して、ジョブを Flink スタンドアロンクラスターに送信します。
./bin/flink-cdc.sh mysql-to-maxcompute.yaml送信が成功すると、次の情報が返されます。
Pipeline has been submitted to cluster. Job ID: f9f9689866946e25bf151ecc179ef46f Job Description: Sync MySQL Database to MaxComputeFlink Web UI では、
Sync MySQL Database to MaxComputeという名前のジョブが実行中であることを確認できます。 -
MaxCompute で次の SQL を実行し、orders、shipments、products の 3 つのテーブルが正常に作成され、データが書き込まれていることを確認します。
-- ordersテーブルを表示 read orders; -- 戻り値: +------------+------------+ | id | price | +------------+------------+ | 1 | 4 | | 2 | 100 | +------------+------------+ -- shipmentsテーブルを表示 read shipments; -- 戻り値 +------------+------------+ | id | city | +------------+------------+ | 1 | beijing | | 2 | xian | +------------+------------+ -- productsテーブルを表示 read products; -- 戻り値 +------------+------------+ | id | product | +------------+------------+ | 3 | Peanut | | 1 | Beer | | 2 | Cap | +------------+------------+
変更操作の同期
ここでは orders テーブルを例に、MySQL データベースのソーステーブルのデータを変更すると、MaxCompute の対応するターゲットテーブルのデータもリアルタイムで更新されることを示します。
-
次のコマンドを実行して MySQL コンテナに入ります。
docker-compose exec mysql mysql -uroot -p123456 -
MySQL の orders テーブルにデータを 1 件挿入します。
INSERT INTO app_db.orders (id, price) VALUES (3, 100.00);MaxCompute で
read orders;コマンドを実行して orders テーブルのデータをクエリします。戻り値は次のとおりです。+------------+------------+ | id | price | +------------+------------+ | 3 | 100 | | 1 | 4 | | 2 | 100 | +------------+------------+ -
MySQL の orders テーブルにフィールドを 1 つ追加します。
ALTER TABLE app_db.orders ADD amount varchar(100) NULL;MaxCompute で
read orders;コマンドを実行して orders テーブルのデータをクエリします。戻り値は次のとおりです。+------------+------------+------------+ | id | price | amount | +------------+------------+------------+ | 3 | 100 | NULL | | 1 | 4 | NULL | | 2 | 100 | NULL | +------------+------------+------------+ -
MySQL の orders テーブルのデータを 1 件更新します。
UPDATE app_db.orders SET price=100.00, amount=100.00 WHERE id=1;MaxCompute で
read orders;コマンドを実行して orders テーブルのデータをクエリします。戻り値は次のとおりです。+------------+------------+------------+ | id | price | amount | +------------+------------+------------+ | 3 | 100 | NULL | | 1 | 100 | 100.00 | | 2 | 100 | NULL | +------------+------------+------------+ -
MySQL の orders テーブルからデータを 1 件削除します。
DELETE FROM app_db.orders WHERE id=2;MaxCompute で
read orders;コマンドを実行して orders テーブルのデータをクエリします。戻り値は次のとおりです。+------------+------------+------------+ | id | price | amount | +------------+------------+------------+ | 3 | 100 | NULL | | 1 | 100 | 100.00 | +------------+------------+------------+
上記の操作について、MySQL で各ステップを実行するたびに MaxCompute でデータプレビューを行うと、MaxCompute に表示される orders テーブルのデータがリアルタイムで更新されることがわかります。
ルート機能
Flink CDC には、ソーステーブルの構造やデータを他のテーブル名にルーティングするための設定が用意されています。この機能を利用して、テーブル名やデータベース名の置換、データベース全体の同期などを実現できます。以下に設定ファイルの説明を示します。
################################################################################
# 説明: MySQLのすべてのテーブルをMaxComputeに同期します
################################################################################
source:
type: mysql
hostname: localhost
port: 3306
username: root
password: 123456
tables: app_db.\.*
server-id: 5400-5404
server-time-zone: UTC
# accessId、accessKey、endpoint、projectはユーザー自身で入力する必要があります
sink:
type: maxcompute
name: MaxComputeSink
accessId: ${your_accessId}
accessKey: ${your_accessKey}
endpoint: ${your_maxcompute_endpoint}
project: ${your_project}
bucketsNum: 8
route:
- source-table: app_db.orders
sink-table: ods_db.ods_orders
- source-table: app_db.shipments
sink-table: ods_db.ods_shipments
- source-table: app_db.products
sink-table: ods_db.ods_products
pipeline:
name: Sync MySQL Database to MaxCompute
parallelism: 1
route 部分のパラメーターの詳細については、「Flink CDC Route」をご参照ください。
上記の route 設定により、app_db.orders テーブルの構造とデータが ods_db.ods_orders へ同期されます。これにより、データベース移行の機能が実現します。特に、source-table は正規表現による複数テーブルのマッチングをサポートしているため、シャーディングされたデータベースとテーブルの同期機能も実現できます。例えば、以下の設定です。
route:
- source-table: app_db.order\.*
sink-table: ods_db.ods_orders
これにより、app_db.order01、app_db.order02、app_db.order03 のようなテーブルのデータを ods_db.ods_orders に集約できます。
現在、複数のテーブルに同じプライマリキーのデータが存在するシナリオには対応していません。この機能は将来のバージョンで対応予定です。
環境のクリーンアップ
上記の操作が完了したら、環境をクリーンアップする必要があります。
-
docker-compose.yaml ファイルのあるディレクトリで、次のコマンドを実行してすべてのコンテナを停止します。
docker-compose down -
Flink のディレクトリ flink-1.18.0 で、次のコマンドを実行して Flink クラスターを停止します。
./bin/stop-cluster.sh
付録
コネクタの設定項目
|
設定項目 |
必須 |
デフォルト値 |
型 |
説明 |
|
type |
はい |
none |
String |
使用するコネクタを指定します。ここでは |
|
name |
いいえ |
none |
String |
シンクの名前です。 |
|
accessId |
はい |
none |
String |
Alibaba Cloud アカウントまたは RAM ユーザーのアクセスキー ID です。AccessKey管理ページから取得できます。 |
|
accessKey |
はい |
none |
String |
アクセスキー ID に対応する AccessKey シークレットです。 |
|
endpoint |
はい |
none |
String |
MaxCompute サービスへの接続アドレスです。MaxCompute プロジェクトを作成した際に選択したリージョンとネットワーク接続方式に基づいてエンドポイントを設定する必要があります。各リージョンとネットワークに対応するエンドポイントについては、「エンドポイント」をご参照ください。 |
|
project |
はい |
none |
String |
MaxCompute プロジェクト名です。MaxCompute コンソールにログインし、ワークスペース > プロジェクト管理 のページで MaxCompute プロジェクト名を取得できます。 |
|
tunnelEndpoint |
いいえ |
none |
String |
MaxCompute Tunnel サービスへの接続アドレスです。通常、この設定は指定されたプロジェクトが存在するリージョンに基づいて自動的にルーティングされます。この設定は、プロキシなどの特殊なネットワーク環境でのみ使用します。 |
|
quotaName |
いいえ |
none |
String |
MaxCompute のデータ転送に使用する専用リソースグループの名前です。この設定を指定しない場合は、共有リソースグループが使用されます。詳細については、「専用データ転送リソースグループの購入と使用」をご参照ください。 |
|
stsToken |
いいえ |
none |
String |
RAM ロールによって発行された一時的なアクセストークン (STS トークン) を使用して認証する場合、このパラメーターを指定する必要があります。 |
|
bucketsNum |
いいえ |
16 |
Integer |
MaxCompute の Delta テーブルを自動作成する際に使用するバケット数です。使用方法については、「ほぼリアルタイムデータウェアハウスの概要」をご参照ください。 |
|
compressAlgorithm |
いいえ |
zlib |
String |
MaxCompute への書き込み時に使用するデータ圧縮アルゴリズムです。現在、 |
|
totalBatchSize |
いいえ |
64 MB |
String |
メモリ内でバッファリングされるデータ量です。単位はパーティションレベルです (非パーティションテーブルの場合はテーブルレベル)。異なるパーティション (テーブル) のバッファは互いに独立しており、しきい値に達するとデータが MaxCompute に書き込まれます。 |
|
bucketBatchSize |
いいえ |
4 MB |
String |
メモリ内でバッファリングされるデータ量です。単位はバケットレベルで、Delta テーブルへの書き込み時にのみ有効です。異なるデータバケットのバッファは互いに独立しており、しきい値に達するとそのバケットのデータが MaxCompute に書き込まれます。 |
|
numCommitThreads |
いいえ |
16 |
Integer |
チェックポイント段階で、同時に処理できるパーティション (テーブル) の数です。 |
|
numFlushConcurrent |
いいえ |
4 |
Integer |
MaxCompute にデータを書き込む際に、同時に書き込めるバケットの数です。Delta テーブルへの書き込み時にのみ有効です。 |
|
retryTimes |
いいえ |
3 |
Integer |
ネットワーク接続でエラーが発生した場合のリトライ回数です。 |
|
sleepMillis |
いいえ |
5000 |
Long |
ネットワーク接続でエラーが発生した場合、各リトライの待機時間です。単位:ミリ秒。 |
テーブル位置のマッピング
コネクタはテーブルを自動作成する際に、以下のマッピング関係を使用して、ソーステーブルの位置情報を MaxCompute テーブルにマッピングします。
MaxCompute プロジェクトが Schema モデルに対応していない場合、各同期ジョブは 1 つの MySQL Database のみを同期できます (他のデータソースも同様に、コネクタは tableId.namespace 情報を無視します)。
|
Flink CDC 内のオブジェクト |
MaxCompute の位置 |
MySQL の位置 |
|
設定ファイル内の project |
Project |
none |
|
TableId.namespace |
Schema (MaxCompute プロジェクトが Schema モデルに対応している場合のみ。対応していない場合、この設定は無視されます) |
Database |
|
TableId.tableName |
Table |
Table |
データ型マッピング
|
Flink Type |
MaxCompute Type |
|
CHAR/VARCHAR |
STRING |
|
BOOLEAN |
BOOLEAN |
|
BINARY/VARBINARY |
BINARY |
|
DECIMAL |
DECIMAL |
|
TINYINT |
TINYINT |
|
SMALLINT |
SMALLINT |
|
INTEGER |
INTEGER |
|
BIGINT |
BIGINT |
|
FLOAT |
FLOAT |
|
DOUBLE |
DOUBLE |
|
TIME_WITHOUT_TIME_ZONE |
STRING |
|
DATE |
DATE |
|
TIMESTAMP_WITHOUT_TIME_ZONE |
TIMESTAMP_NTZ |
|
TIMESTAMP_WITH_LOCAL_TIME_ZONE |
TIMESTAMP |
|
TIMESTAMP_WITH_TIME_ZONE |
TIMESTAMP |
|
ARRAY |
ARRAY |
|
MAP |
MAP |
|
ROW |
STRUCT |