数据同步和访问日志实时收集

757 阅读3分钟

1 Canal增量数据同步利器

1.1 Canal介绍

canal主要用途是基于 MySQL 数据库增量日志解析,并能提供增量数据订阅和消费,应用场景十分丰富。

github地址:github.com/alibaba/can…

版本下载地址:github.com/alibaba/can…

文档地址:github.com/alibaba/can…

Canal应用场景

1.电商场景下商品、用户实时更新同步到至Elasticsearch、solr等搜索引擎; 2.价格、库存发生变更实时同步到redis; 3.数据库异地备份、数据同步; 4.代替使用轮询数据库方式来监控数据库变更,有效改善轮询耗费数据库资源。 image.png

数据同步和访问日志实时收集

MySQL主从复制原理

  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events)
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

image.png Canal工作原理

1.canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议 2.MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal ) 3.canal 解析 binary log 对象(原始为 byte 流)

1.2 Canal安装

配置MySQL

需要让canal伪装成salve并正确获取mysql中的binary log,首先要开启 Binlog 写入功能,配置 binlog-format 为 ROW 模式

修改MySQL配置文件,如下操作:

# 执行修改命令
vi /etc/my.cnf

找不到配置文件的可能是你安装的时候没有配置MySQL的配置文件,参考这篇博文配置 # linux下查看mysql的配置文件

# 配置文件 mysql.cnf 内容如下
[mysqld]
# 设置关闭二进制日志
#skip-log-bin# 开启二进制日志
log-bin=mysql-bin
​
#开启binlog 选择ROW模式
binlog-format=ROW
​
#server_id不要和canal的slaveId重复
server_id=1
​
​
​

配置文件修改完成后重启MySQL

docker restart seckill_mysql

在MySQL中执行以下sql,查询数据库状态

show variables like 'log_bin';
show variables like 'binlog_format';
show master status;

创建连接MySQL的账号canal并授予作为 MySQL slave 的权限,执行以下sql:

# 创建账号
CREATE USER canal IDENTIFIED BY 'canal'; 
# 授予权限
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
# 修改数据库加密算法,如果数据库是5.7及以下版本,这句话不需要执行
ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal'; 
# 刷新并应用
FLUSH PRIVILEGES;

创建并配置Cancal

安装cancal参考这篇博文 Canal软件安装,数据同步操作流程

配置Canal

# 进入Canal容器
docker exec -it canal-server /bin/bash

# 修改完成后重启Canal服务
docker restart canal-server

看到这些日志就表示启动成功

image.png

监听数据库表的配置 canal.instance.filter.regex 如下:

mysql 数据解析关注的表,Perl正则表达式.
多个正则之间以逗号(,)分隔,转义符需要双斜杠(\) 
常见例子:
1.  所有表:.*   or  .*\..*
2.  canal schema下所有表: canal\..*
3.  canal下的以canal打头的表:canal\.canal.*
4.  canal schema下的一张表:canal.test1
5.  多个规则组合使用:canal\..*,mysql.test1,mysql.test2 (逗号分隔)
注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为不解析sql,所以无法准确提取tableName进行过滤)