-
缓存双删:如果公司现有消息队列中间件,可以考虑使用该方案,反之则不需要考虑。
-
先写数据库再删缓存:这种方法从实时性以及技术实现复杂度来说都不错,推荐方案。
-
Binlog异步更新:实现最终一致性以及数据多中心模式。
Canal是什么?有什么用?
Canal是数据库的一个组件,是基于MySQL数据库增量日志解析,提供增量数据订阅和消费,支持将增量数据投递到下游消费者(MQ)或者存储(ES)的组件。
Canal 能够检测数据库的变动,然后解析变动数据,将变动数据发送到MQ或者同步到其他数据库,等待进一步的业务处理。
MySQL主从复制原理?
MySQL master 将数据库变更操作记录到binary log日志中,简称binlog。
MySQL slave 将master中的binary log拷贝到它的中继日志(relay log)中。
MySQL slave 重放relay log 操作,将变更数据同步到最新。
什么是binlog?介绍一下场景和他的分类?
binlog是MySQL中最重要的日志,记录了DDL(data definition language)(create,drop,alter,truncate和rename)和DML(data manipulation language)(insert,update,delete和select)语句,以事件的形式记录。
默认不开启,开启会有1%的性能损耗。
场景:
1.部署集群,数据库需要主从复制的情况下,需要开启Binlog。
2.数据库需要进行数据恢复时,使用MySQL Binlog 工具来恢复数据。
分类:
名称 | 介绍 | 优点 | 缺点 |
---|---|---|---|
STATEMENT | 语句级别,记录的是SQL语句 | 节省空间 | 可能会造成数据不一致 |
ROW | 行级,记录的是每一行数据的变化 | 数据的一致性非常高 | 占用空间很大 |
MIXED | STATEMENT的升级版本,在特定情况下会使用ROW进行处理,使数据一致性得到保证。 | 节省空间的同时,对一致性有一定的保证。 | 有些极个别情况会导致数据不一致,另外statement和mixed对于需要binlog监控的情况不方便。 |
综上分析,选择row类的binlog用作canal监控。
Canal的工作原理?
-
Canal将自己伪装成一个MySQL slave,向主库master发送dump协议
-
主库收到dump协议,开始向Canal发送binlog。
-
Canal收到binlog后开始解析,得到变更的数据,执行后续的逻辑。
使用和binlog保证数据库一致性的工作流程?
1.在MySQL中开启binlog。使用 show variables like 'log_%'; 检查log是否开启。
2.MySQL执行SQL语句创建canal单独使用的账号,用来进行binlog的同步和监听。
3.开始配置canal中间件,将canal.properties文件中的配置改为自己本地的mq配置。
4.instance.properties配置MySQL地址和端口。
5.双击startup.bat脚本启动canal。
6.更改数据库中的一条数据如:将t_seat表中的任意一条数据的 seat_status 的值从1变为0或者从0变为1。
7.查看mq控制台,查看详细消息体(消息体格式为JSON)。
8.在Springboot与RocketMQ对接。
(如果监听多张表的数据,分发模式是通过策略模式找到对应的策略实现类。具体的策略实现类在canal目录下。
正式开始:
1.数据过滤
为何进行数据过滤?我们明白,若监听了 t_seat 表的 Binlog 数据变化,即使对任意字段进行修改,都会引发变更流程,从而将数据传送至 RocketMQ 消息队列,随后客户端会消费此消息。但实际关注的是 seat_status 字段的改变,例如由 0(可售状态)转变为 1(锁定状态),或者从 1 变为 0。只有这种数据变化才需要更新相应的余票缓存,其他字段的变化并不需要触发后续逻辑。因此,在此阶段,若非预期的数据变动,可直接过滤。
2.更新列车站点余票缓存逻辑。
检测座位状态是否在 0(可售状态)和 1(锁定状态)之间进行变化。当从 0 到 1 变化时,表示生成了订单需要减少库存。若由 1 变为 0,则表示订单被取消或超时关闭,需要增加列车库存。 因此,判定自增或自减库存,我们仅需考虑旧数据的 seatStatus 是否为 0。若为 0,则表示新数据已变更为 1,需要自减列车站点库存;反之,自增库存。 由于 Binlog 可能一次触发多个数据变更,我们将这些操作整理至一个 Map,以进行统一操作。