# 目的
面对越来越繁杂的业务，重大的修改很容易导致。系统的不稳定，所以需要采用非业务侵入的方案，对数据进行收集或转发

这里采用 cancal 对mysql binlog数据进行订阅

# Cancal 初步介绍
Canal，意为“水道”，形象地比喻其作为数据流动的管道，主要功能是基于MySQL数据库的增量日志解析，实现增量数据的实时订阅和消费

项目起源于阿里巴巴内部对于跨机房数据同步的需求，通过解析MySQL的二进制日志（Binary Log），Canal能够捕获并推送数据库的变更事件，满足了诸如数据库镜像、实时备份、索引实时维护等多种业务场景的需求

Canal巧妙地模拟了MySQL主从复制的机制。具体而言
- `伪装为MySQL Slave`：Canal向MySQL Master发送dump请求，假装自己是一个MySQL Slave
- `获取Binary Log`: MySQL Master接收到请求后，开始推送Binary Log给Cancal
- `解析日志事件`: Canal解析接收到的Binary Log，将数据变更信息转换为易于处理的结构化数据

# 数据订阅方案
![数据订阅方案](../images/data_sync/binlog_cancal_1.png)

通过 Cancal 对 binlog 数据订阅

并通过 [cancal-php](https://gitee.com/lujihong/canal-php) 客户端获取binlog 具体数据，为了提高数据的吞吐率，可以使用Redis 队列(或者其他队列)具体处理对应的业务

#  配置项
## Cancal
### canal/conf/example/instance.properties
```properties
# 数据源配置
canal.instance.master.address=mysql:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal

# 在Mysql执行 SHOW MASTER STATUS;查看当前数据库的binlog
canal.instance.master.journal.name=mysql-bin.000006
canal.instance.master.position=4596

# 过滤规则（同步所有库表）
canal.instance.filter.regex=.*\\..*

# 存储模式（内存）
canal.instance.memory.store=true
```
## binlog 配置
```
[mysqld]
# 打开binlog
log-bin=mysql-bin
# 选择ROW(行)模式
binlog-format=ROW
# mysql实例唯一id，但是切记不能与下文中需要配置的canal的slaveId重复
server_id=1
```

# docker-compose.yml 配置
deepseek 生成(未验证)
```yaml
version: '3.8'

services:
  # 依赖的 MySQL 数据库
  mysql:
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root          # Root 用户密码
      MYSQL_DATABASE: test               # 初始数据库
      MYSQL_USER: canal                  # 创建 Canal 专用用户
      MYSQL_PASSWORD: canal
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d   # 挂载 MySQL 配置
      - ./mysql/data:/var/lib/mysql      # 持久化数据
    networks:
      - canal-network

  # Canal 服务
  canal:
    image: canal/canal-server:v1.1.7     # 官方镜像已包含 Java 环境
    container_name: canal-server
    depends_on:
      - mysql
    ports:
      - "11111:11111"                   # Canal 默认服务端口
    environment:
      # Canal 全局配置
      canal.auto.scan: "true"            # 自动扫描实例配置
      canal.instance.memory.store: "true"
      # MySQL 连接配置
      canal.instance.master.address: mysql:3306
      canal.instance.dbUsername: canal
      canal.instance.dbPassword: canal
      canal.instance.filter.regex: .*\\..*
    volumes:
      - ./canal/conf:/home/admin/canal-server/conf   # 挂载自定义配置
      - ./canal/logs:/home/admin/canal-server/logs   # 持久化日志
    networks:
      - canal-network

networks:
  canal-network:
    driver: bridge
```


# 参考资料
- [Canal：MySQL Binlog解析与增量数据订阅实战指南](https://blog.csdn.net/qq_29752857/article/details/138482952)
- [canal-php](https://gitee.com/lujihong/canal-php)
- [深入浅出阿里数据同步神器：Canal原理+配置+实战全网最全解析！](https://developer.aliyun.com/article/1179561)
- [Canal1.1.5最新版安装部署及详细配置(1)](https://blog.csdn.net/lizz861109/article/details/112369812)
- [Mysql配置binlog操作](https://blog.csdn.net/lizz861109/article/details/112378004)
- [canal使用指南（一）](https://blog.csdn.net/imVainiycos/article/details/122077960)
- [使用Canal同步MySQL数据](https://help.aliyun.com/zh/tablestore/use-cases/use-canal-to-synchronize-data)
- [一篇文章让你上手Canal数据同步神技~](https://blog.csdn.net/langfeiyes/article/details/130711899)
- [数据同步工具之FlinkCDC/Canal/Debezium对比](https://cloud.tencent.com/developer/article/1893807)