docker 安装部署 canal

1 mysql 安装

1.1 拉取镜像

shell 复制代码
docker pull mysql:8.4.4

1.2 创建挂载目录

shell 复制代码
mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf
shell 复制代码
mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/data
shell 复制代码
mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/log

1.3 编辑配置文件

在配置文件挂载目录 /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf 编写配置文件 my.cnf 内容如下:

shell 复制代码
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'

max_connections = 5000
wait_timeout = 20000
max_user_connections = 5000
max_allowed_packet = 128M
thread_stack = 262144

# 时区设置
default-time-zone = '+08:00'

# 允许创建函数(防止报错)
log_bin_trust_function_creators = 1

# 开启慢查询日志
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/slow-query.log
long_query_time = 3
log_output = FILE

# 开启主从复制(Canal 需要用到)
log-bin = mysql-bin
binlog-format = ROW
server_id = 1

以下是对该 MySQL 配置文件的按功能分析:

字符集设置
  • 配置项

    ini 复制代码
    [client]
    default-character-set = utf8mb4
    
    [mysql]
    default-character-set = utf8mb4
    
    [mysqld]
    character-set-server = utf8mb4
    collation-server = utf8mb4_general_ci
    init_connect = 'SET NAMES utf8mb4'
  • 分析

    • utf8mb4 字符集:支持存储所有 Unicode 字符,避免了 utf8 的三字节限制,适用于多语言和表情符号等。
    • utf8mb4_general_ci 排序规则:不区分大小写,适合大部分应用场景,但对于某些语言,可能有更精确的排序规则(例如 utf8mb4_unicode_ci)。
    • init_connect:每次连接时都会执行 SET NAMES utf8mb4,确保客户端连接使用 UTF-8 编码。
连接数和性能配置
  • 配置项

    ini 复制代码
    max_connections = 5000
    wait_timeout = 20000
    max_user_connections = 5000
    max_allowed_packet = 128M
    thread_stack = 262144
  • 分析

    • 最大连接数 (max_connections = 5000):允许最多 5000 个并发连接,适合高并发应用。
    • 等待超时 (wait_timeout = 20000):连接最大空闲时间为 20000 秒(大约 5.5 小时),适用于长时间运行的会话或连接。
    • 每个用户最大连接数 (max_user_connections = 5000):限制每个用户的最大并发连接数为 5000,避免某个用户占用过多连接资源。
    • 最大数据包大小 (max_allowed_packet = 128M):允许最大数据包为 128MB,适用于大数据量传输。
    • 线程栈大小 (thread_stack = 262144):增加线程栈大小,防止在执行复杂查询或存储过程时栈溢出。
时区设置
  • 配置项

    ini 复制代码
    default-time-zone = '+08:00'
  • 分析

    • 设置时区为 UTC+08:00,通常用于中国和东南亚,确保时间存储和显示的一致性。
函数创建权限
  • 配置项

    ini 复制代码
    log_bin_trust_function_creators = 1
  • 分析

    • 允许创建存储函数和触发器,即使启用了二进制日志功能。这个设置解决了在启用二进制日志时,无法创建涉及存储过程或触发器的函数的问题。
慢查询日志
  • 配置项

    ini 复制代码
    slow_query_log = ON
    slow_query_log_file = /var/lib/mysql/slow-query.log
    long_query_time = 3
    log_output = FILE
  • 分析

    • 开启慢查询日志 (slow_query_log = ON):记录执行时间超过指定阈值的查询,帮助识别性能瓶颈。
    • 日志文件路径 (slow_query_log_file = /var/lib/mysql/slow-query.log):慢查询日志将写入到指定文件,便于后续分析。
    • 慢查询阈值 (long_query_time = 3):超过 3 秒的查询被认为是慢查询并记录下来。
    • 日志输出方式 (log_output = FILE):慢查询日志输出到文件,而非其他方式(例如表格或系统日志)。
主从复制配置
  • 配置项

    ini 复制代码
    log-bin = mysql-bin
    binlog-format = ROW
    server_id = 1
  • 分析

    • 二进制日志 (log-bin = mysql-bin):启用二进制日志,通常用于主从复制和数据恢复。
    • 日志格式 (binlog-format = ROW):行模式二进制日志记录,确保数据变化的精确记录,比语句模式更稳定,适用于复杂的数据变动。
    • 服务器 ID (server_id = 1):设置服务器唯一标识符,在主从复制或集群环境中,每个 MySQL 实例都需要一个唯一的 server_id

1.4 运行镜像

shell 复制代码
docker run -p 3308:3306 --name mysql_8.4.4 -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf/my.cnf:/etc/mysql/my.cnf -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/data:/var/lib/mysql -v /user/lzl/tool/docker/mysql/mysql_8.4.4/home/log:/var/log/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.4.4

1.5 检查二进制日志开启情况

进入容器

shell 复制代码
docker exec -it 容器id /bin/bash

进入容器后输入命令,登陆mysql

shell 复制代码
 mysql -uroot -p123456

输入命令查看二进制日志是否开启

shell 复制代码
show variables like 'log_bin';

1.6 创建账号供 canal 使用

1.6.1 创建用户

shell 复制代码
create user 'canal'@'mysqlIP' identified by 'canal';

1.6.2 授予权限

shell 复制代码
grant select, replication slave, replication client on *.* to 'canal'@'mysqlIP';

1.6.3 刷新权限

shell 复制代码
FLUSH PRIVILEGES;

1.6.4 删除用户命令

shell 复制代码
drop user '用户名'@'主机';

1.6.5 命令分析

这两条命令用来给用户 canal(只允许从 localhost 连接)赋予以下权限:

  • select:允许查询数据库内容;
  • replication slave:允许该用户从主服务器复制数据(在主从复制中常用);
  • replication client:允许该用户查看主从复制相关状态信息,如主服务器的状态和从服务器连接状态。

同时,通过 identified by 'canal' 指定了该用户的密码为 canal

2 canal 安装

2.1 拉取镜像

shell 复制代码
docker pull canal/canal-server:v1.1.8

2.2 配置文件介绍

2.2.1 /home/admin/canal-server/conf/canal.properties

canal.properties 是 canal 的主要配置文件,用于配置 canal 实例的各项参数。该文件包含了连接 MySQL 数据库、消息队列、数据同步等相关的配置项。

例如 canal.destinations = examplecanal 可以有多个 instance,每个实例有独立的配置文件,默认只 有一个example实例。如果需要处理多个mysql数据的话,可以复制出多个example,对其重新命名, 命令和配置文件中指定的名称一致。然后修改canal.properties 中的 canal.destinations,canal.destinations=实例 1,实例 2,实例 3

2.2.2 /home/admin/canal-server/conf/example/instance.properties

instance.properties 是 canal 中的实例配置文件,用于配置单个 canal 实例的行为。每个 canal 实例对应一个 MySQL 数据库或一个逻辑数据库的同步任务。

2.2.2.1 MySQL 连接配置

这些配置项用于 Canal 连接 MySQL 数据库,从 binlog 中获取数据。

properties 复制代码
# MySQL serverId(一般设置为不同的唯一值,避免与 MySQL 主库的 server_id 冲突)
# v1.0.26+ 版本会自动生成
# canal.instance.mysql.slaveId=0
  • canal.instance.mysql.slaveId :如果 MySQL 只有一个实例,可以不配置这个参数,或者设置一个唯一的 slaveId(如 2)。
properties 复制代码
# MySQL 主库地址
canal.instance.master.address=127.0.0.1:3306
  • canal.instance.master.address:指定 Canal 连接的 MySQL 主库的地址。
properties 复制代码
# MySQL 账号信息(需要具备 REPLICATION SLAVE 权限)
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
  • canal.instance.dbUsername & canal.instance.dbPassword:用于 Canal 访问 MySQL 读取 binlog 数据。
properties 复制代码
# MySQL 连接字符集(一般使用 UTF-8)
canal.instance.connectionCharset = UTF-8
  • canal.instance.connectionCharset:设置 MySQL 连接的字符集。

2.2.2.2 GTID 相关配置
properties 复制代码
# 是否启用 GTID(全局事务 ID),默认为 false
canal.instance.gtidon=false
  • canal.instance.gtidon:是否启用 MySQL 的 GTID(适用于 MySQL 5.6+),一般不需要启用。
properties 复制代码
# GTID 相关参数(一般不需要配置)
canal.instance.master.gtid=
  • canal.instance.master.gtid:如果使用 GTID,可以在这里指定初始 GTID。

2.2.2.3 Binlog 读取位置
properties 复制代码
# binlog 读取位置(如果为空,会从 MySQL 最新的 binlog 开始读取)
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=
  • canal.instance.master.journal.name & canal.instance.master.position :用于指定从哪个 binlog 开始读取数据(如果为空,则从最新的 binlog 位置开始)。

2.2.2.4 数据表过滤
properties 复制代码
# 允许同步的表(正则表达式,默认匹配所有数据库和表)
canal.instance.filter.regex=.*\\..*
  • canal.instance.filter.regex :默认匹配 所有数据库所有表.*\..* 表示 所有库.所有表)。
properties 复制代码
# 黑名单(不需要同步的表)
canal.instance.filter.black.regex=mysql\\.slave_.*
  • canal.instance.filter.black.regex :排除 mysql 系统库中的 slave_* 相关表。

2.2.2.5 备库(Standby)配置
properties 复制代码
# 如果 Canal 需要连接备份数据库(备用数据库)
# canal.instance.standby.address=
# canal.instance.standby.journal.name=
# canal.instance.standby.position=
# canal.instance.standby.timestamp=
# canal.instance.standby.gtid=
  • canal.instance.standby.address:如果 Canal 需要连接一个备用 MySQL 实例(主库故障时可切换到备用库)。

2.2.2.6 时序数据库(TSDB)支持
properties 复制代码
# 是否启用 table meta tsdb(用于存储表结构变更历史)
canal.instance.tsdb.enable=true
  • canal.instance.tsdb.enable:启用表结构变更的存储功能,防止因表结构变化导致 binlog 解析失败。

2.2.2.7 SSL 相关配置
properties 复制代码
# MySQL SSL 连接配置(默认禁用)
# canal.instance.master.sslMode=DISABLED
# canal.instance.master.tlsVersions=
# canal.instance.master.trustCertificateKeyStoreType=
# canal.instance.master.trustCertificateKeyStoreUrl=
# canal.instance.master.trustCertificateKeyStorePassword=
  • SSL 相关配置:如果需要 MySQL 使用 SSL 连接,可配置证书路径。

2.2.2.8 Canal 消息队列(MQ)配置

Canal 支持对接 Kafka、RocketMQ、RabbitMQ 等消息队列。

properties 复制代码
# MQ 的 topic 名称
canal.mq.topic=example
  • canal.mq.topic:指定 Canal 发送数据到消息队列的 Topic 名称。
properties 复制代码
# MQ 分区
canal.mq.partition=0
  • canal.mq.partition:指定 Canal 数据写入到 Kafka/RocketMQ 的分区。
properties 复制代码
# 是否启用动态队列分区
# canal.mq.enableDynamicQueuePartition=false
# canal.mq.partitionsNum=3
  • canal.mq.enableDynamicQueuePartition :是否启用 动态队列分区(Kafka/RocketMQ 支持)。
properties 复制代码
# 根据表的哈希值进行分区
# canal.mq.partitionHash=test.table:id^name,.*\\..*
  • canal.mq.partitionHash :用于指定某些表按照 idname 进行分区。

2.2.2.9 其他高级配置
properties 复制代码
# 是否启用 Druid 解析数据库密码(加密存储密码)
canal.instance.enableDruid=false
  • canal.instance.enableDruid:是否启用 Druid 数据源解析数据库密码。
properties 复制代码
# canal.instance.pwdPublicKey=...
  • canal.instance.pwdPublicKey :如果 enableDruid=true,可以配置公钥进行加密。

2.2.2.10 总结

instance.properties 配置文件主要包括:

  1. MySQL 连接信息canal.instance.master.address)。
  2. Binlog 读取控制canal.instance.master.journal.nameposition)。
  3. 数据库表过滤canal.instance.filter.regex)。
  4. 备库切换canal.instance.standby.address)。
  5. 时序数据库(TSDB)支持canal.instance.tsdb.enable)。
  6. SSL 安全连接canal.instance.master.sslMode)。
  7. 消息队列(MQ)支持canal.mq.topiccanal.mq.partition)。
  8. Druid 数据源密码加密canal.instance.enableDruid)。

这些配置可以根据实际需求进行调整,比如:

  • 如果 Canal 需要对接 Kafka,则要调整 canal.mq.topic
  • 如果 Canal 只同步特定表,需要修改 canal.instance.filter.regex
  • 如果 MySQL 启用了 GTID,需要配置 canal.instance.gtidon=true

2.3 创建挂载目录

shell 复制代码
mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs
shell 复制代码
mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf
shell 复制代码
mkdir -p /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example

授权:

shell 复制代码
chmod 777 /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home

运行容器:

shell 复制代码
docker run -p 11111:11111 --name canal_server_v1.8.8 -d canal/canal-server:v1.1.8

复制配置文件到挂载目录:

shell 复制代码
docker cp canal_server_v1.1.8:/home/admin/canal-server/conf/canal.properties /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/canal.propertiesls
shell 复制代码
docker cp canal_server_v1.1.8:/home/admin/canal-server/conf/example/instance.properties /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example/instance.properties

卸载容器:

shell 复制代码
docker rm -f  canal_server_v1.8.8

2.4 修改配置文件

修改 canal.properties,如果使用默认配置不用修改

shell 复制代码
# 默认端口 11111
# 默认输出model为tcp, mysql就使用tcp
# tcp, kafka, RocketMQ
#canal.serverMode = tcp

#################################################
######### destinations ############# 
#################################################
# canal可以有多个instance,每个实例有独立的配置文件,默认只 有一个example实例。
# 如果需要处理多个mysql数据的话,可以复制出多个example,对其重新命名,
# 命令和配置文件中指定的名称一致。然后修改canal.properties 中的 canal.destinations
# canal.destinations=实例 1,实例 2,实例 3
#canal.destinations = example

修改 instance.properties,只需要修改mysql地址即可

shell 复制代码
# 不能和mysql master重复
canal.instance.mysql.slaveId=2
# 使用mysql的虚拟ip和端口 需要改
canal.instance.master.address=172.17.0.2:3306
# 使用已创建的canal用户 默认就有
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8
# canal.instance.defaultDatabaseName =test

# 表示匹配所有的库所有的表 默认就是
canal.instance.filter.regex =.*\\..*

2.5 重启 canal 容器

shell 复制代码
docker run --name canal_server_v1.8.8 -p 11111:11111 -d \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/conf/example/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-v /user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs/:/home/admin/canal-server/logs/ \
canal/canal-server:v1.1.8

2.7 检测是否连接成功

查看实例日志(日志:/user/lzl/tool/docker/canal-server/canal-server_v1.1.8/home/logs/example/example.log),发现报错如下:

shell 复制代码
Caused by: java.io.IOException: Error When doing Client Authentication:ErrorPacket [errorNumber=1524, fieldCount=-1, message=Plugin 'mysql_native_password' is not loaded, sqlState=HY000, sqlStateMarker=#]
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.negotiate(MysqlConnector.java:332)
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:81)
	... 4 common frames omitted

根本原因是 canal 使用 mysql_native_password 认证插件,而 mysqlc使用的认证插件为 caching_sha2_password

mysql 查询用户认证插件:

shell 复制代码
SELECT user, host, plugin FROM mysql.user WHERE user = 'canal';

由于高版本 mysql 默认禁用 mysql_native_password ,所以需要修改 mysql 配置文件:

shell 复制代码
vim /user/lzl/tool/docker/mysql/mysql_8.4.4/home/conf/my.cnf
shell 复制代码
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'

max_connections = 5000
wait_timeout = 20000
max_user_connections = 5000
max_allowed_packet = 128M
thread_stack = 262144

# 时区设置
default-time-zone = '+08:00'

# 允许创建函数(防止报错)
log_bin_trust_function_creators = 1

# 开启慢查询日志
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/slow-query.log
long_query_time = 3
log_output = FILE

# 开启主从复制(Canal 需要用到)
log-bin = mysql-bin
binlog-format = ROW
server_id = 1

mysql_native_password=ON

重启 mysql 容器:

shell 复制代码
docker restart mysql_8.4.4

进入mysql 容器修改用户认证插件:

shell 复制代码
docker exec -it mysql_8.4.4 /bin/bash
shell 复制代码
mysql -uroot -p123456
shell 复制代码
ALTER USER 'canal'@'mysqlIP' IDENTIFIED WITH mysql_native_password BY 'canal';

刷新权限:

shell 复制代码
FLUSH PRIVILEGES;

下面的图只是实例,'canal'@'mysqlIP' 改成实际 ip

运行成功命令 example.log:

shell 复制代码
2025-03-24 03:17:20.549 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 
2025-03-24 03:17:21.220 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table filter : ^.*\..*$
2025-03-24 03:17:21.220 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table black filter : ^mysql\.slave_.*$
2025-03-24 03:17:21.226 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
2025-03-24 03:17:21.388 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position
2025-03-24 03:17:21.388 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - prepare to find start position just show master status
2025-03-24 03:17:21.453 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.otter.canal.parse.inbound.mysql.MysqlConnection - load MySQL @@version_comment : MySQL Community Server - GPL
2025-03-24 03:17:22.963 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=mysql-bin.000004,position=4,serverId=1,gtid=<null>,timestamp=1742785681000] cost : 1555ms , the next step is binlog dump
2025-03-24 03:17:23.065 [destination = example , address = /113.45.38.93:3308 , EventParser] WARN  c.a.otter.canal.parse.inbound.mysql.MysqlConnection - load MySQL @@version_comment : MySQL Community Server - GPL

提示:mysql 创建 canal 用户时 不要用 localhost 直接用实际 ip ,网上有的博客使用的时 localhost,但是我的是失败的。

3 canal 同步数据到 ES

3.1 引入依赖

java 复制代码
<!-- https://mvnrepository.com/artifact/com.alibaba.otter/canal.client -->
<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.1.8</version>
</dependency>

<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.protocol</artifactId>
    <version>1.1.8</version>
</dependency> 

3.2 配置信息

未完待续

相关推荐
阿俊仔(摸鱼版)5 小时前
Ubuntu上安装Docker
linux·ubuntu·docker
故事与他6455 小时前
Thinkphp(TP)框架漏洞攻略
android·服务器·网络·中间件·tomcat
帽儿山的枪手7 小时前
程序员必掌握docker六种网络模式
网络协议·docker·容器
每次的天空8 小时前
项目总结:GetX + Kotlin 协程实现跨端音乐播放实时同步
android·开发语言·kotlin
青花锁8 小时前
Ubuntu 系统部署 Ollama + DeepSeek + Docker + Ragflow
linux·ubuntu·docker·deepseek
m0_748233179 小时前
SQL之delete、truncate和drop区别
android·数据库·sql
郭逍遥10 小时前
GZCTF平台搭建及题目上传
笔记·学习·ubuntu·docker·容器
小参宿10 小时前
告别流媒体会员!如何用Docker搭建可远程控制的家庭音乐服务器
服务器·docker·容器
CYRUS_STUDIO11 小时前
OLLVM 增加 C&C++ 字符串加密功能
android·c++·安全
{⌐■_■}11 小时前
【PostgreSQL】pg各版本选用取舍逻辑与docker安装postgres:15
数据库·docker·postgresql