はじめに
Canalは、Alibabaが開発したオープンソースのツールで、MySQLのbinlogを解析し、リアルタイムでデータ変更を他のシステムに同期するために使用されます。この記事では、Canalを用いて単一のMySQLインスタンスおよび複数のMySQLインスタンスを監視し、データを別のデータベースに同期するための設定手順を詳しく説明します。
前提条件
設定を開始する前に、以下の準備が必要です。
- 少なくとも1台のサーバー(テスト環境ではDockerを使用可能)
- Docker、MySQL、JDKのインストール
- Canalのソースコード(GitHubまたはGiteeからダウンロード)
デプロイメント
1. プロジェクトのビルド
Canalのソースコードを取得後、Mavenを使用してプロジェクトをビルドします。以下のコマンドを実行してください。
mvn clean install -DskipTests
2. ファイルのパッケージング
ビルドが成功すると、以下のディレクトリにデプロイメント用のファイルが生成されます。
- deployer:
deployモジュールのtargetディレクトリ内にあるcanalフォルダをリネームして圧縮します。 - canal-adapter:
client-adapterモジュールのlauncherモジュールのtargetディレクトリ内の対応するフォルダを圧縮します。
3. サーバーへのアップロードと設定
圧縮したファイルをサーバーにアップロードし、以下のコマンドで実行権限を付与し、改行コードを調整します。
chmod u+x startup.sh stop.sh restart.sh
sed -i 's/\r$//' startup.sh stop.sh restart.sh
JDK 11を使用する場合は、startup.shファイル内のメモリ設定を以下のように調整する必要があります。
if [ -n "$str" ]; then
JAVA_OPTS="-server -Xms2048m -Xmx3072m -Xmn1024m -XX:SurvivorRatio=2 -Xss256k"
else
JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m"
fi
設定ファイルの構成
シナリオ1:単一のデータソースを単一のデータベースに同期
deployerの設定
conf/example/instance.propertiesファイルを編集し、以下の設定を変更します。
# 監視対象のMySQLサーバーアドレス
canal.instance.source.host=192.168.31.119:3306
canal.instance.source.journal.name=
canal.instance.source.position=
canal.instance.source.timestamp=
canal.instance.source.gtid=
# ユーザー名とパスワード
canal.instance.dbUsername=root
canal.instance.dbPassword=123456
canal.instance.connectionCharset = UTF-8
# 監視するデータベースとテーブルを正規表現で指定
canal.instance.filter.regex=inventory.products
# メッセージブローカーのトピック
canal.mq.topic=instanceA
canal-adapterの設定
conf/application.ymlファイルを編集します。
srcDataSources:
sourceDB: # 監視するデータソース
url: jdbc:mysql://192.168.31.119:3306/inventory?useUnicode=true
username: root
password: 123456
canalAdapters:
- instance: instanceA # canalインスタンス名
groups:
- groupId: syncGroup
outerAdapters:
- name: logger
- name: rdb
key: targetDB
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.31.208:3306/inventory?useUnicode=true
jdbc.username: root
jdbc.password: 123456
次に、テーブルマッピングファイル(例: products_mapping.yml)を作成し、以下の内容を追加します。
dataSourceKey: sourceDB
destination: instanceA
groupId: syncGroup
outerAdapterKey: targetDB
concurrent: true
dbMapping:
database: inventory
table: products
targetTable: products
targetPk:
id: id
mapAll: true
シナリオ2:複数のデータソースを単一または複数のデータベースに同期
deployerの設定
1. conf/canal.propertiesファイルを編集し、複数のインスタンスを定義します。
canal.destinations = instanceA,instanceB
2. conf/exampleディレクトリ内に、instanceAとinstanceBという名前のサブディレクトリを作成し、それぞれにinstance.propertiesファイルをコピーして設定を変更します。
instanceAの設定 (instanceA/instance.properties):
# 監視対象のMySQLサーバーアドレス
canal.instance.source.host=192.168.31.119:3306
...
canal.instance.filter.regex=inventory.products
canal.mq.topic=instanceA
instanceBの設定 (instanceB/instance.properties):
# 監視対象のMySQLサーバーアドレス
canal.instance.source.host=192.168.31.221:3306
...
canal.instance.filter.regex=school.students
canal.mq.topic=instanceB
canal-adapterの設定
conf/application.ymlファイルを編集し、複数のデータソースとインスタンスを設定します。
srcDataSources:
sourceDB1: # インスタンスAのデータソース
url: jdbc:mysql://192.168.31.119:3306/inventory?useUnicode=true
username: root
password: 123456
sourceDB2: # インスタンスBのデータソース
url: jdbc:mysql://192.168.31.221:3306/school?useUnicode=true
username: root
password: 123456
canalAdapters:
# インスタンスAの設定
- instance: instanceA
groups:
- groupId: syncGroup
outerAdapters:
- name: logger
- name: rdb
key: targetDB
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.31.208:3306/inventory?useUnicode=true
jdbc.username: root
jdbc.password: 123456
# インスタンスBの設定
- instance: instanceB
groups:
- groupId: syncGroup
outerAdapters:
- name: logger
- name: rdb
key: targetDB
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.31.208:3306/school?useUnicode=true
jdbc.username: root
jdbc.password: 123456
各インスタンスに対応するテーブルマッピングファイルを作成します。
instanceA用のマッピングファイル (products_mapping.yml):
dataSourceKey: sourceDB1
destination: instanceA
groupId: syncGroup
outerAdapterKey: targetDB
concurrent: true
dbMapping:
database: inventory
table: products
targetTable: products
targetPk:
id: id
mapAll: true
instanceB用のマッピングファイル (students_mapping.yml):
dataSourceKey: sourceDB2
destination: instanceB
groupId: syncGroup
outerAdapterKey: targetDB
concurrent: true
dbMapping:
database: school
table: students
targetTable: students
targetPk:
id: id
mapAll: true
トラブルシューティング
「src-data-sources」プロパティの値を設定できない
このエラーは、JDBC URLの形式が原因であることがあります。URLに以下のパラメータを追加して修正してください。
jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false