Canalを用いたMySQLデータ同期の設定方法:単一インスタンスと複数インスタンスの監視

はじめに

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ディレクトリ内に、instanceAinstanceBという名前のサブディレクトリを作成し、それぞれに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

タグ: Canal MySQL データ同期 binlog YAML

6月12日 17:30 投稿