• 初识Canal以及使用Docker安装配置


    前言

    所有博客文件目录索引:博客目录索引(持续更新)

    一、认识Canal

    canal-github仓库

    Canal介绍:Canal 是用 Java 开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件(数据库同步需要阿里的 Otter 中间件,基于 Canal)。

    Canal背景:阿里巴巴 B2B 公司,因为业务的特性,卖家主要集中在国内,买家主要集中在国外,所以衍生出了同步杭州和美国异地机房的需求,从 2010 年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务。

    Canal原理:自己伪装成 Slave,假装从 Master 复制数据,实际上就是主从复制的一个流程(通过增量复制来不断的进行订阅消费数据)

    • 主从复制原理:

      • 1)Master 主库将改变记录,写到二进制日志(Binary Log)中; 
        2)Slave 从库向 MySQL Master 发送 dump 协议,将 Master 主库的 binary log events 拷贝到它的中继日志(relay log); 
        3)Slave 从库读取并重做中继日志中的事件,将改变的数据同步到自己的数据库。
        
        • 1
        • 2
        • 3

    binlog的分类:statement、row、mixed。在canal配合mysql时,mysql需要配置binlog模式为row(推荐)。

    • statement:记录每一次执行写操作的sql语句,但是可能会产生数据不一致,例如sql语句update tt set create_date=now(),其中就有now()函数,若是其他从结点进行同步就会出现问题。
    • row:记录每次操作后每行记录的变化,直接记录的是数据,能够保持数据的一致性,缺点就是比较占空间。
    • mixed:statement 的升级版,默认实质还是statement,对于uuid()、auto_increment会使用row模式处理,还算是比较智能,但是极个别情况还是会造成数据不一致,并且由于默认依旧是statement,实际上就是sql+数据形式。

    常用场景

    1、异地数据库的同步。

    2、更新缓存。(例如以往的对应某些数据库表字段会设置缓存,处理更新数据库时的字段对缓存进行更新,在高并发的情况下会造成数据一致性问题,此时可以使用canal)

    3、抓取数据更新,来进行实时数据分析。

    二、安装配置Canal

    当前安装的MySQL版本:5.7.36,Canal版本是1.1.5。

    Docker的安装可见:快速使用Docker部署MySQL、Redis、Nginx

    2.1、Docker快速安装MySQL 5.7.56

    canal对于mysql的提前配置文档:canal-quickstart

    下载mysql:

    docker pull mysql:5.7.36
    
    • 1

    启动mysql服务:

    # 首先运行这个容器(目的是拷贝其中的配置文件)
    docker run --name mysql5736 \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=root \
    -d mysql:5.7.36
    
    # 复制mysql5.7.36的配置文件(注意:若是你使用不同版本的对应位置要进行修改)
    docker cp mysql5736:/etc/mysql/mysql.conf.d/mysqld.cnf  /mydata/mysql/conf
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    复制的配置文件如下:

    image-20220821170712565

    # 配置文件中添加如下内容,注意是在在[mysqld]目录中
    log-bin=mysql-bin  # 开启 binlog
    binlog-format=ROW  # 选择 ROW 模式
    server-id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
    
    • 1
    • 2
    • 3
    • 4

    接着我们进行下面真正启动容器命令:

    # 删除之前启动的docker容器(我们需要添加一些新的启动项参数)
    docker rm -f mysql5736
    
    # 运行docker容器命令
    # --name mysql5736:容器名为mysql5736
    # /etc/localtime:时间同步
    # /mydata/mysql/conf:同步配置文件(这个是关键,上面配置的内容就会覆盖容器中的配置文件)
    # /mydata/mysql/log:同步日志目录
    # /mydata/mysql/data:同步mysql的一些文件内容(对数据进行备份)
    # MYSQL_ROOT_PASSWORD=root:默认root的密码是root
    docker run --name mysql5736 \
    -p 3306:3306 \
    -v /etc/localtime:/etc/localtime \
    -v /mydata/mysql/conf:/etc/mysql/mysql.conf.d \
    -v /mydata/mysql/log:/var/log/mysql \
    -v /mydata/mysql/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=root \
    -d mysql:5.7.36
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    接下来我们进入到mysql的命令行模式来给root账号授权所有ip能够访问,授权好之后我们可以用navicat来进行连接:

    # 使用mysql容器中的命令行
    docker exec -it mysql5736 /bin/bash
    
    # 使用MySQL命令打开客户端:
    mysql -uroot -proot --default-character-set=utf8
    
    # 接着创建一个账户,该账号所有ip都能够访问
    grant all privileges on *.* to 'root' @'%' identified by 'root';
    
    # 刷新生效
    FLUSH PRIVILEGES;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    创建canal账号并去授权 canal ,为了之后canal进行连接mysql的账户:

    -- 创建用户名密码都是canal的账号
    CREATE USER canal IDENTIFIED BY 'canal';  
    
    -- 为canal进行授权读取、client从、客户端权限
    grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';
    
    -- 刷新生效
    FLUSH PRIVILEGES;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意:一定要查看bin-log是否已经开启,下面的命令我们可以去进行一个查看当前mysql的信息:

    # 查看binlog日志是否开启
    show variables like 'log_%';
    
    # 查看主结点当前状态
    show master status
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image-20220820210816977

    image-20220821172956011

    此时我们也可以在对应的/mydata/mysql/data中查看到bin-log日志情况:

    image-20220820210927775

    2.2、Docker快速安装Canal 1.1.5

    Canal下载地址

    tar压缩包安装:官方文档

    Docker安装的官方文档:Canal Docker QuickStart

    拉取Canal的镜像文件:

    docker pull canal/canal-server:v1.1.5
    
    • 1

    首次启动容器,并拷贝配置文件:

    # 启动容器(目的是拷贝配置文件)
    docker run --name canal115 \
    -p 11111:11111  \
    -id canal/canal-server:v1.1.5
    
    # 提前创建 /mydata/canal/conf目录,接着来执行拷贝配置文件命令
    docker cp canal115:/home/admin/canal-server/conf/example/instance.properties  /mydata/canal/conf/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    image-20220820220249499

    复制好配置文件之后,我们来对这个properties进行修改,下面的内容在配置文件中若是注释状态就打开并修改:

    # 从机id(与之前mysql配置的id不同)
    canal.instance.mysql.slaveId=2  
    
    # 指定ip地址也是可以的,查看方式docker inspect --format '{{ .NetworkSettings.IPAddress }}'  mysql
    # 容器进行了--link,这里mysql5736就是对应的服务地址
    canal.instance.master.address=mysql5736:3306  
    
    # 用户名与密码
    canal.instance.dbUsername=canal
    canal.instance.dbPassword=canal
    
    # 匹配全部数据库
    canal.instance.filter.regex = .\*\\\\..\*  
    
    canal.mq.topic=example  # 目的地队列
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    执行命令启动canal容器:

    # 删除原先的canal服务
    docker rm -f canal115
    
    # 启动canal服务
    # -i:让容器的标准输入保持打开(特别特别重要,注意不要是-d,一定要加上i)
    docker run --name canal115 \
    -p 11111:11111  \
    -v /mydata/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
    --link mysql5736:mysql5736 \
    -id canal/canal-server:v1.1.5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    启动完canal之后,去查看canal实例的日志内容,判断是否已经成功连接到mysql:

    # 进入到docker容器
    docker exec -it canal115 /bin/bash
    
    # 打开日志文件
    cd canal-server/logs/example/
    
    # 查看日志文件的最后100行内容
    tail -100 example.log 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    下面是连接成功的情况:

    image-20220821171626947


    另外贴出连接失败情况(折腾了一天了快,最后终于解决):

    image-20220821095248862

    BioSocketChannelPool默认超时时间不够,导致连接出错 Docker整合canal 踩坑实录

    docker安装并使用阿里巴巴Canal(含安装MySQL、开启binlog、Java代码、填坑经验)

    解决方案

    1、查看用户名、密码是否由权限。

    2、docker运行canal命令检查是否是-id,注意如果是-d我也会出现上面报错!!!

    • 这个解决方案并不是搜索博客解决的,而是看一个实战项目教程,我通过看别人实际能够连接的案例执行命令,找到了这个问题,一定要注意细节!!!
  • 相关阅读:
    如何处理海量数据文件以及大文件数据查找
    【数据库原理及应用】——事务并发控制和恢复技术(学习笔记)
    fdbus之事件循环及线程关系
    微服务网关Gateway实践总结
    git 命令行其实真的很好用
    Web自动化测试 —— 如何进行Selenium页面数据及元素交互?啊哈
    Xgboost报错 ValueError: Invalid shape: (1650, 2) for label
    专栏汇总(一)
    N位质数c++
    深入理解嵌入式系统【基于Arduino的嵌入式系统入门与实践】相关基础知识概述:嵌入式系统/技术(定义、分类、组成、简介);Arduino开发板分类;VCC,GND;模拟信号和数字信号;杜邦线,面包板
  • 原文地址:https://blog.csdn.net/cl939974883/article/details/126460634