通过dockerfile搭建canal用于同步mysql数据到clickhouse

645 阅读3分钟

先上结论

虽然canal支持使用mysql同步数据到clickhouse,但是目前canal并没有办法处理更新、删除。

失策了,一开始没有注意到,折腾了好久最后发现不能用,舍不得删掉就记录下来,如果不是同步到clickhouse应该还是具有参考价值的。

正文

看了很多材料,有些真的没办法直接用,反正这个我跑通了,建议可以先照搬再修改。

canal 版本 1.1.5,需要 mysql clickhouse rabbitmq或其他canal支持方式

mysql配置 my.cnf

现有配置中追加,开启binlog

server-id = 1
log-bin = /var/lib/mysql/bin.log
binlog-format = row
expire-logs-days = 30
max-binlog-size = 768M

目录结构

├── data
│   ├── canal
├── files
│   ├── canal
│   │   ├── config
│   │   │   ├── adapter
│   │   │   │   ├── rdb
│   │   │   │   │   └── demo-table.yml # 见下文
│   │   │   │   └── application.yml # 见下文
│   │   │   └── deployer
│   │   │       ├── canal.properties    # 见下文
│   │   │       └── instance.properties # 见下文
│   │   ├── libs # 这些jar包 https://mvnrepository.com/ 在这里找找吧
│   │   │   ├── clickhouse-jdbc-0.2.jar
│   │   │   ├── httpclient-4.5.5.jar
│   │   │   ├── httpcore-4.4.9.jar
│   │   │   ├── lz4-1.3.0.jar
│   │   │   └── lz4-java-1.4.1.jar
│   │   ├── Dockerfile # 见下文
│   │   ├── canal.adapter-1.1.5.tar.gz # 下载 https://github.com/alibaba/canal/releases
│   │   ├── canal.deployer-1.1.5.tar.gz # 下载 https://github.com/alibaba/canal/releases
│   │   └── jdk-8u301-linux-x64.rpm # 这个。。自己找吧
│   └── docker-compose.yml

Dockerfile

FROM centos:7

COPY ./canal.*.tar.gz /data/
COPY ./jdk-8u301-linux-x64.rpm /data/jdk-8u301-linux-x64.rpm
WORKDIR /data

RUN \
    yum install -y /data/jdk-8u301-linux-x64.rpm man dstat unzip nc openssh-server which perl file && \
    mkdir /data/canal.deployer && \
    tar zxvf canal.deployer-*.tar.gz -C /data/canal.deployer && \
    mkdir /data/canal.adapter && \
    tar zxvf canal.adapter-*.tar.gz -C /data/canal.adapter && \
    rm -f /data/canal*.tar.gz && \
    rm -f /data/jdk-8u301-linux-x64.rpm && \
    true

COPY ./libs/*.jar /data/canal.adapter/lib/

docker-compose.yml

这部分可能要自己弄一弄,这里关键部分可以参考

command 最后一句是一个死循环不然容器无法保持,比较蠢,有好方法请赐教

version: '3.2'
networks:
  my_bridge:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: "172.19.0.0/24"
services:
  canal:
    container_name: canal
    build: ./canal
    volumes:
      - ./canal/config/deployer/instance.properties:/data/canal.deployer/conf/example/instance.properties:rw
      - ./canal/config/deployer/canal.properties:/data/canal.deployer/conf/canal.properties:rw
      - ../data/canal/deployer/logs:/data/canal.deployer/logs
      - ./canal/config/adapter/application.yml:/data/canal.adapter/conf/application.yml:rw
      - ./canal/config/adapter/rdb:/data/canal.adapter/conf/rdb:rw
      - ../data/canal/adapter/logs:/data/canal.adapter/logs
    ports:
      - "8089:8089"
    restart: always
    command: 
      - /bin/bash
      - -c
      - |
          /data/canal.deployer/bin/startup.sh
          /data/canal.adapter/bin/startup.sh
          echo "start~~~~" > /xx.log && tail -f /xx.log

config/deployer/canal.properties

只截取有修改与增加的部分,用下载的包里的那个同名文件来改

# tcp, kafka, rocketMQ, rabbitMQ
canal.serverMode = rabbitMQ

# 这里是mq的配置,需要建好一个交换机且与一个队列绑定,建议看一下参考资料
# 这个配置的最后
canal.mq.servers = # mq的ip地址
# 这些模版里没有的,但是似乎这个有效
canal.mq.vhost=/   
canal.mq.exchange= # 交换机
canal.mq.username= # 用户名
canal.mq.password= # 密码
canal.mq.aliyunuid=

# 这下面的配置是模版里有的。。但是配了似乎无效,反正我是都配了,你可以自己试一下哪个管用,不过还是先跑通再改

##################################################
######### 		    RabbitMQ	     #############
##################################################
rabbitmq.host = ip:5672 # mq连接地址
rabbitmq.virtual.host =/
rabbitmq.exchange =ck-exchange
rabbitmq.username = # 用户名
rabbitmq.password = # 密码
rabbitmq.deliveryMode =

config/deployer/instance.properties

只截取有修改与增加的部分,用下载的包里的那个同名文件来改 这里是数据源配置

canal.instance.master.address=xxx:3306 # mysql连接地址:端口

# mysql账号密码
canal.instance.dbUsername=root
canal.instance.dbPassword=密码

# 监控的变化的表,正则,这里写的是demo_db数据库下的demo_table
# 可以使用 demo_db\\.* 监控demo_db下所有表
# 多个单表可以逗号间隔如 demo_db\\.demo_table1,demo_db\\.demo_table2
canal.instance.filter.regex=demo_db\\.demo_table

# mq交换机绑定队列时的routekey
canal.mq.topic=ck-routekey

config/adapter/application.yml

server:
  port: 8081
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    default-property-inclusion: non_null

canal.conf:
  #tcp kafka rocketMQ rabbitMQ
  mode: rabbitMQ
  flatMessage: true
  zookeeperHosts:
  syncBatchSize: 1000
  retries: 0
  timeout:
  accessKey:
  secretKey:
  consumerProperties:
    rabbitmq.host: xxx:5672 mq连接地址:端口
    rabbitmq.virtual.host: /
    rabbitmq.username: mq用户名
    rabbitmq.password: mq密码
    rabbitmq.resource.ownerId: 

  canalAdapters:
    - instance: ck-queue
      groups:
      - groupId: g1
        outerAdapters:
        - name: logger
        - name: rdb
          key: mysql1
          properties:
            jdbc.driverClassName: ru.yandex.clickhouse.ClickHouseDriver
            jdbc.url: jdbc:clickhouse://clickhouse地址:8123/库名 # jdbc连接
            jdbc.username: clickhouse用户名
            jdbc.password: clickhouse密码

config/adapter/rdb/demo-table.yml

这里的官方文档的rdb配置说明 github.com/alibaba/can…

dataSourceKey: defaultDS
destination: 绑定的队列名称
groupId: g1
outerAdapterKey: mysql1
concurrent: true
dbMapping:
  database: msql来源库名
  table: mysql来源表名
  targetTable: clickhouse目标表名,应该是因为前一个jdbc中写了库名,所以这里不能以 库.表 的方式配置,你可以试试jdbc去掉库名
  mapAll: true # 完整映射字段
  commitBatch: 3000 # 批量提交的大小

以上所有配置都可以在canal官方文档中得到一定解释,想自定义一些见官方文档

参考链接(感谢作者)

使用Canal-1.1.5实现ClickHouse实时同步MySQL数据(rabbitmq版) juejin.cn/post/696986…