背景
业务需要做数据同步:当mysql新增或者更新数据后需要同步到es库,后续的查询都是去es查询。
缓存数据同步:配置类的文件一般缓存到redis中,当更新数据库后,需要删除缓存
安装mysql(8.0)
下载mysql https://dev.mysql.com/downloads/mysql/ 下载222.3M的安装包即可
下载到本地后,解压到D:\app\mysql-8.0.31-winx64,此时目录如下:
bin
docs
include
lib
share
LICENSE
README
在解压目录增加my.ini的配置文件,文件内容如下
[client]
port=3306
[mysql]
default-character-set=utf8
[mysqld]
port = 3306
basedir=D:\app\mysql-8.0.31-winx64
datadir=D:\app\mysql-8.0.31-winx64\data
max_connections=200
character-set-server=utf8
default-storage-engine=INNODB
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
然后打开cmd模式(尽量开管理员运行),切换到D:\app\mysql-8.0.31-winx64\bin目录,按照如下步骤执行:
执行安装
mysqld.exe install [服务名称]
成功提示如下信息:Service successfully installed.
如果不输入服务名称,默认是mysql。如果有,比如mysqld.exe install mysql-slave 那么服务名称就是mysql-slave
初始化数据目录
mysqld.exe --initialize
成功后会在安装目录生成data文件夹
启动服务
net start mysql
需要注意,mysql是安装时的服务名称。我们安装时如果时mysql-slave,那么启动的时候需要用 net start mysql-slave
第一次登录
第一次登录的账号密码是随机的,在data目录的xxx.err文件。打开后找到这句。HL<2.#PCgvw,就是密码。
2022-12-27T06:34:31.495346Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: HL<2.#PCgvw,
然后在cmd控制台输入
mysql -u root -p [-p完了以后回车]
Enter your password: 【这里提示输入密码,再把随机密码输入】
登录以后第一件事就是修改密码
mysql> alter user 'root'@'localhost' identified by '123456';Query OK, 0 rows affected (0.00 sec)mysql> exitBye
安装kafka
安装canal
下载canal https://github.com/alibaba/canal/releases
下载完成后,解压即可,然后配置配置文件:
canal的几个核心配置:指定监听的数据库,指定数据推送模式是kafka,指定kafka相关的配置
conf/example/instance.properties
canal.instance.master.address=127.0.0.1:3306 #配置监听哪个数据库canal.instance.dbUsername=root #账号密码是master中创建的一组,需要有较高权限哦canal.instance.dbPassword=123456canal.mq.topic=ofpCanalDataPayment #指定kafka推送的topic
conf/canal.properties
canal.serverMode = kafka # 需要指定模式为kafka,默认是tcpkafka.bootstrap.servers = c01.kafka.ofp.dev:9092,c02.kafka.ofp.dev:9092,c03.kafka.ofp.dev:9092 #指定kafka的brokers
然后启动 bin/startup.bat
第一次启动的成功标识是:logs/canal/canal.log 有类似日志
2020-06-02 11:26:13.159 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler
2020-06-02 11:26:13.206 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations
2020-06-02 11:26:13.220 [main] INFO com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server.
2020-06-02 11:26:13.263 [main] INFO com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[127.0.0.1(127.0.0.1):11111]
2020-06-02 11:26:13.264 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## the canal server is running now ......
logs/example/example.log 有类似日志
2020-06-02 11:37:18.102 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
2020-06-02 11:37:18.105 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
2020-06-02 11:37:18.301 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
2020-06-02 11:37:18.301 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
2020-06-02 11:37:18.697 [main] INFO c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example
2020-06-02 11:37:18.713 [main] INFO c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
FAQ:
Canal ABA问题:数据消费了,但是数据库和es数据依然是不同步的
A:数据消费逻辑导致出现ABA问题。正常场景是:A数据更新->推A到es->拉取A关联的属性数据B->推B。远端业务处理逻辑是:A更新->B更新
canal数据消费是多线程并行。就导致:
A更新->kafka->推A到es->拉B(旧数据)->推B(旧)
↓
B更新->kafka->推B到es(新)
出现了ABA问题。解决思路:
串行消费,那么逻辑就将变成
A更新->kafka->推A到es->拉B(新旧均有可能)-> 推B
↓ ↓
B更新->kafka ............................>推B到es
需要注意的是,这里依然可能产生ABA问题:如果canal消费端的逻辑是拿到数据后需要反查mysql数据,则存在ABA的可能。先放图
从图中可以看出,binlog的消息在commit之前就发出去了。若是用spring的事务注解,可以将一大块逻辑包含在一个事务,例如同时更新表A和表B。但是如果表A更新后,经过较长时间才处理完表B,那么释放事务时间就太靠后了。也会出现aba问题。
A更新->长时间处理->B更新,释放事务
canalA消费,从数据库拉取A推送(在没有释放事务的时候,将得到旧数据)