windows下使用canal-adapter mysql同步es7

环境:

win11 x64

jdk1.8

docker

mysql:5.7.36(docker镜像安装)

es7(docker镜像安装)

canal-adapter1.1.5

canal-deployer1.1.6 (直接使用的docker镜像,版本也是1.1.6)

除canal相关的其它软件正常安装就行,下面直接介绍数据同步的相关操作

安装elasticsearch

docker pull elasticsearch:7.16.2
docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --name='es7162' -d elasticsearch:7.16.2

docker启动es:

图片

 

然后我们需要配置一下es的信息:

docker exec -ites es7162 /bin/bash
cd config
vi elasticsearch.yml

配置文件:

cluster.name: dailyhub-es
network.host: 0.0.0.0

node.name: node-1
http.port: 9200
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true

docker restart es7162 重启es,注意千万别写错配置的信息,否则启动会失败,启动失败是后可以通过docker logs -f es7162查看原因,但也只能重新来了。
然后服务器访问:

// 查询es所有mapping
http://119.45.25.164:9200/_mapping?pretty=true

注意如果是云服务器的话,要在安全组中配置对应的端口开放、还有防火墙啥的,然后安全些的话,还需要给es配合账号密码啥的。

 

安装canal-server

拉取镜像并启动:

docker pull canal/canal-server:v1.1.6

docker run --name canal115 -p 11111:11111  --link mysql5736:mysql5736 -id canal/canal-server:v1.1.6

修改对应的配置:

docker exec -it canal115 /bin/bash
cd canal-server/conf/example/
vi instance.properties  // 修改配置

# 把0改成10,只要不和mysql的id相同就行
canal.instance.mysql.slaveId=10
# 修改成mysql对应的账号密码,mysql5736就是mysql镜像的链接别名
canal.instance.master.address=mysql5736:3306
canal.instance.dbUsername=root
canal.instance.dbPassword=admin

 

 

验证配置是否成功:

#首先重启一下canal
docker restart  canal115

docker exec -it canal115 /bin/bash
cd canal-server/logs/example/
tail -100f example.log  // 查看日志

截图如下,说明已经链接上了mysql主机,此时mysql中的数据变化,都会在canal中有同步。

图片

可以通过Java程序测试有没连接上mysql:

导入canal-client包

<!-- 为了测试canal-server是否连接mysql成功,1.1.5版本少包,所以用1.1.4版本 -->
<dependency>
   <groupId>com.alibaba.otter</groupId>
   <artifactId>canal.client</artifactId>
   <version>1.1.4</version>
</dependency>
  • com.markerhub.SimpleCanalClientExample
    /**
    * 公众号:MarkerHub
    *
    * 说明:用于测试canal是否已经连接上了mysql
    */
    public class SimpleCanalClientExample {
      public static void main(String args[]) {
          // 创建链接
          CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("119.45.25.164",
                  11111), "example", "", "");
          int batchSize = 1000;
          int emptyCount = 0;
          try {
              connector.connect();
              connector.subscribe(".*\\..*");
              connector.rollback();
              int totalEmptyCount = 120;
              while (emptyCount < totalEmptyCount) {
                  Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据
                  long batchId = message.getId();
                  int size = message.getEntries().size();
                  if (batchId == -1 || size == 0) {
                      emptyCount++;
                      System.out.println("empty count : " + emptyCount);
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                      }
                  } else {
                      emptyCount = 0;
                      // System.out.printf("message[batchId=%s,size=%s] \n", batchId, size);
                      printEntry(message.getEntries());
                  }
                  connector.ack(batchId); // 提交确认
                  // connector.rollback(batchId); // 处理失败, 回滚数据
              }
              System.out.println("empty too many times, exit");
          } finally {
              connector.disconnect();
          }
      }
      private static void printEntry(List<Entry> entrys) {
          for (Entry entry : entrys) {
              if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
                  continue;
              }
              RowChange rowChage = null;
              try {
                  rowChage = RowChange.parseFrom(entry.getStoreValue());
              } catch (Exception e) {
                  throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(),
                          e);
              }
              EventType eventType = rowChage.getEventType();
              System.out.println(String.format("================> binlog[%s:%s] , name[%s,%s] , eventType : %s",
                      entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
                      entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
                      eventType));
              for (RowData rowData : rowChage.getRowDatasList()) {
                  if (eventType == EventType.DELETE) {
                      printColumn(rowData.getBeforeColumnsList());
                  } else if (eventType == EventType.INSERT) {
                      printColumn(rowData.getAfterColumnsList());
                  } else {
                      System.out.println("-------> before");
                      printColumn(rowData.getBeforeColumnsList());
                      System.out.println("-------> after");
                      printColumn(rowData.getAfterColumnsList());
                  }
              }
          }
      }
      private static void printColumn(List<Column> columns) {
          for (Column column : columns) {
              System.out.println(column.getName() + " : " + column.getValue() + "    update=" + column.getUpdated());
          }
      }
    }
    当mysql的数据更新时候效果如下:

    图片

注意当后面canal-adapter也连接上canal-server后,程序就监听不到数据变化了。

安装canal-adapter 1.1.5

重点来了,这个比较坑,不同版本会出现不同的问题,我这里使用1.1.7和1.1.6都出现一些不同的BUG解决起来都比较麻烦,最终选择1.1.5这个版本

首先说一下,这个docker没有官方镜像,不过有第三方封装的镜像,我没有使用,这里提供一下拉取地址(版本号可根据情况进行选择)

docker pull slpcat/canal-adapter:v1.1.5

docker run --name adapter115 -p 8081:8081 --link mysql5736:mysql5736 --link canal115:canal115 --link es7162:es7162 -d slpcat/canal-adapter:v1.1.5

 docker安装和客户端运行配置都是一样的,接下来开始爬坑。

客户端安装(重点)

首先在官网下载

地址:Release v1.1.5 · alibaba/canal (github.com)

下载好后解压到一个没有中文的路径下面(空格也不行)

注意:路径如果不对会影响后边操作

 打开conf文件夹下的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:
  mode: tcp #tcp kafka rocketMQ rabbitMQ
  flatMessage: true
  zookeeperHosts:
  syncBatchSize: 1000
  retries: 0
  timeout:
  accessKey:
  secretKey:
  consumerProperties:
    # canal tcp consumer
    canal.tcp.server.host: canal115:11111
    canal.tcp.zookeeper.hosts:
    canal.tcp.batch.size: 500
    canal.tcp.username:
    canal.tcp.password:
  srcDataSources:
    defaultDS:
      url: jdbc:mysql://mysql5736:3306/dailyhub?useUnicode=true
      username: root
      password: admin
  canalAdapters:
  - instance: example # canal instance Name or mq topic name
    groups:
    - groupId: g1
      outerAdapters:
      - name: logger
      - name: es7
        hosts: es7162:9200 # 127.0.0.1:9200 for rest mode
        properties:
          mode: rest
          # security.auth: test:123456 #  only used for rest mode
          cluster.name: dailyhub-es

 

接下来打开conf/es7文件夹,拷贝一份mytest_user.yml重命名dailyhub_collect.yml

配置文件:

dataSourceKey: defaultDS
destination: example
groupId: g1
esMapping:
  _index: dailyhub_collect
  _id: _id
  _type: _doc
  upsert: true
#  pk: id
  sql: "
SELECT
        c.id AS _id,
        c.user_id AS userId,
        c.title AS title,
        c.url AS url,
        c.note AS note,
        c.collected AS collected,
        c.created AS created,
        c.personal AS personal,
        u.username AS username,
        u.avatar AS userAvatar
FROM
        m_collect c
LEFT JOIN m_user u ON c.user_id = u.id

"
#  objFields:
#    _labels: array:;
#   etlCondition: "where c.c_time>={}"
  commitBatch: 3000

注意对于时间类型,在后端一定要使用LocalDateTime或者LocalDate类型,如果是Date类型,需要自己手动设置格式。

到这里基本就配置完成,接下来是遇到的问题,保证所有配置没问题的报错

java.lang.ClassCastException: com.alibaba.druid.pool.DruidDataSource cannot be cast to com.alibaba.druid.pool.DruidDataSource

原因是 druid 包冲突导致的,解决办法如下

下载源码包

wget https://github.com/alibaba/canal/archive/refs/tags/canal-1.1.5.tar.gz

解压后,使用IDEA打开,定位到 client-adapter.escore 模块的 pom.xml 的 druid 更新为

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <scope>provided</scope>
</dependency>

更新后,在项目根目录下执行

mvn clean package

然后到 canal-canal-1.1.5/client-adapter/es7x/target 下 将打包好的 client-adapter.es7x-1.1.5-jar-with-dependencies.jar 替换掉 canal-adapter/plugin 下原来的

重启 Canal Adapter,发现日志不再报错,问题成功解决。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值