java监听mysql数据表变化_另辟蹊径,MySQL主从同步延
迟,这样解决也挺好
⼀、canal是个啥?
canal是阿⾥开发的⼀款基于数据库增量⽇志解析,提供增量数据订阅与消费的框架,整个框架纯JAVA开发,⽬前仅⽀持Mysql和MariaDB(和mysql类似)。
那什么是数据库增量⽇志?
MySQL的⽇志种类是⽐较多的,主要包含:错误⽇志、查询⽇志、慢查询⽇志、事务⽇志、⼆进制⽇志。⽽MySQL数据库所发⽣的数据变更(DML(data manipulation language)数据操纵语⾔,也就是我们熟悉的增删改),都会以⼆进制⽇志(binary log)形式存储。
⼆、canal原理
在介绍canal原理之前,我们先来回顾⼀下MySQL主从同步的原理,这或许会让你更好的理解canal的⼯作机制。
1、MySQL主从同步原理:
MySQL主从同步也叫读写分离,可以提升数据库的负载和容错能⼒,实现数据库的⾼可⽤
先来分析⼀张MySQL主从同步原理图:
以上图⽚源⾃⽹络,如有侵权联系删除
master节点操作过程:
当master节点数据发⽣更改后(delete、update、insert,还是创建函数、存储过程等操作),向binary log中写⼊记录⽇志,这些记录⼜叫做⼆进制⽇志事件(binary log events)。
show binlog events
  这些事件会按照顺序写⼊bin log中。当slave节点启动连接到master节点的时候,master节点会为slave节点开启binlog dump线程(负责传输binlog数据)。
⼀旦master节点的bin log发⽣变化时,bin logdump线程会通知slave节点有可以传输的binlog,并将相应的bin log内容发送给slave节点。
slave节点操作过程:
slave节点上会创建两个线程:⼀个I/O线程,⼀个SQL线程。I/O线程连接到master节点,master节点
上的binlog dump 线程会将binlog 的内容发送给该IO线程。
该I/O线程接收到binlog内容后,再将内容写⼊到本地的relay log。⽽sql线程读取到I/O线程写⼊的ralay log,将relay log中的内容写⼊slave数据库。
2、canal原理
懂了上边MySQL的主从同步原理,canal的⼯作机制就很好理解了。其实canal是模拟了MySQL数据库中,slave节点与master节点的交互协议,伪装⾃⼰为MySQL slave节点,向MySQL master节点发送dump协议,MySQL master节点收到dump请求,开始推送binary log给slave节点(也就是canal)。
以上图⽚源⾃⽹络,如有侵权联系删除
光说不练假把式,开⼲!
三、canal实现“监控”MySQL
在写代码前我们先对MySQL进⾏⼀下改造,安装MySQL就不再细说了,基本操作。
1、查看⼀下MySQL是否开启了binary log功能
show binary logs
如果没有开启是图中的状态,⼀般⽤户是没有这个命令权限的,不过我有,啧啧啧!
如果没有需要⼿动开启,并且在myf⽂件中配置binlog-format 为Row模式
log-bin=mysq-binbinlog-format=Row
log-bin是binlog⽂件存放位置 binlog-format 设置MySQL复制log-bin的⽅式
MySQL的三种复制⽅式:
基于SQL语句的复制(statement-based replication, SBR)
优点:将修改数据的sql保存在binlog,不需要记录每⼀条sql和数据变化,binlog体量会很⼩,IO开销少,性能好
缺点:会导致master-slave中的数据不⼀致
基于⾏的复制(row-based replication, RBR)
优点:不记录每条sql语句的上下⽂信息,仅需记录哪条数据被修改了,修改成什么样了
缺点:binlog体积很⼤,尤其是在alter table属性时,会产⽣⼤量binlog数据
混合模式复制(mixed-based replication, MBR)
对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
2、为canal 创建⼀个有权限操作MySQL的⽤户
CREATE USER canal IDENTIFIED BY 'canal';  GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';-- GRANT ALL PRI
3、安装canal
下载后选择版本例如:canal.
4、配置canal
修改instance.properties⽂件,需要添加监听数据库和表的规则,canal可以全量监听数据库,也可以针对某个表进⾏监听,⽐较灵活。
vim conf/example/instance.properties
>>>>>>>>>># mysql sql.slaveId = 2020# position info 修改⾃⼰的数据库(canal要监听启动canal
sh bin/startup.sh
看⼀下server⽇志,确认⼀下canal是否正常启动
vi logs/canal/canal.log
显⽰canal server is running now即为成功
2020-01-08 15:25:33.361 [main] INFO  canal.deployer.CanalLauncher - ##    start the canal server.2020-01-08 15:25:33.468 [main] INF
5、编写Java客户端代码,实现canal监听
引⼊依赖包
  canal.client  1.1.0复制代码
这⾥只是简单实现
public class MainApp {    public static void args) throws Exception {        /**        * 创建与        */        CanalConnector connector = CanalConnectors.代码到这就编写完成了,我们启动服务看下是什么效果,由于并没有操作数据库,所以监听的结果都是空的。
接下来我们在数据库执⾏⼀条update语句试试
update jk_orderset order_no = '1111'  where id = 40
控制台检测到了数据库的修改,并⽣成binlog ⽇志⽂件mysql-bin.000009:3830
那么⽣成的binlog ⽂件该怎么⽤,如何解析成SQl语句呢?
com.github.shyiko            mysql-binlog-connector-java            0.13.0
将刚才的binlog⽂件下载本地测试⼀下
public static void main(String[] args) throws IOException {        String filePath = "C:ProgramDataMySQLMySQL Server 5.7Datamysql-bin.000009:3830";
查看⼀下执⾏结果,发现数据库最近的⼀次操作是加了⼀个idx_index索引
Event{header=EventHeaderV4{timestamp=1551325542000, eventType=ANONYMOUS_GTID, serverId=1, headerLength=19, dataLength=46, nextPositio
⾄此我们就已经实现了监控MySQL,
mysql下载app四、canal应⽤场景
canal应⽤场景⼤致有以下:
解决MySQL主从同步延迟的问题
实现数据库实时备份
多级索引 (卖家和买家各⾃分库索引)
实现业务cache刷新
价格变化等重要业务消息
重点分析⼀下canal是如何解决MySQL主从同步延迟的问题
⽣产环境下MySQL的主从同步模式(maser-slave)很常见,但对于跨机房部署的集,会出现同步延时的情况。举个栗⼦:
⼀条订单状态是未付款,master节点修改成已付款,可由于某些原因出现延迟数据未能及时同步到slave,这时⽤户⽴即查看订单状态(查
询⾛slave)显⽰还是未付款,哪个⽤户看到这种情况不得慌啊。
为什么会出现主从同步延迟呢?
当主库master的TPS并发较⾼时,master节点并发产⽣的修改操作,⽽slave节点的sql线程是单线程处理同步数据,延时⾃然⽽⾔就产⽣
了。
我们⽤canal实时监听maser节点的数据更新(可以针对某个表监听),canal捕捉到更改的SQL后⽴即在slave节点执⾏,以此来解决主从延迟问题。
不过造成主从同步的原因不⽌这些,由于主从服务器存在跨机器并且跨机房,除了⽹络带宽原因之外,⽹络的稳定性以及机器之间的同步,都是主从同步应该考虑的主要原因。
总结
本⽂只是简单实现canal监听数据库的功能,旨在给⼤家提供⼀种解决问题的思路,还是反复絮叨的那句话,解决问题的技术⽅法很多,具体如何应⽤还需结合具体业务。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论