【Redis】缓存同步
文章目录
- 【Redis】缓存同步
- 1. 数据同步策略
- 2. 异步通知策略
- 3. Canal
- 3.1 Canal客户端
- 3.2 监听器
1. 数据同步策略
缓存数据同步的常见方式有三种:
- 设置有效期:给缓存设置有效期,到期后自动删除,再次查询时更新。
- 优势:简单方便
- 缺点:时效性差,缓存过期之前可能不一致
- 场景:更新频率较低,时效性要求低的业务
- 同步双写:在修改数据库的同时,直接修改缓存。
- 优势:时效性强,缓存与数据库强一致
- 缺点:有代码侵入,耦合度高
- 场景:对一致性、时效性要求较高的缓存数据
- 异步通知:修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据。
- 优势:低耦合,可以同时通知多个缓存服务
- 缺点:时效性一般,可能存在中间不一致状态
- 场景:时效性要求一般,有多个服务需要同步
2. 异步通知策略
基于 MQ 的异步通知:
基于 Canal 的异步通知:
3. Canal
Canal ,译意为水道/管道/沟渠,canal是阿里巴巴旗下的一款开源项目,基于Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。GitHub的地址:https://github.com/alibaba/canal
Canal是基于MySQL的主从同步来实现的:
- MySQL master 将数据变更写入二进制日志( binary log),其中记录的数据叫做binary log events
- MySQL slave 将 master 的 binary log events拷贝到它的中继日志(relay log)
- MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
Canal 就是将自己伪装成mysql的一个slave节点,从而监听 master 的binary log 变化。再把得到的变化信息通知给Canal的客户端,进而完成对其他数据库的同步。
3.1 Canal客户端
Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。
Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。不过这里我们会使用GitHub上的第三方开源的canal-starter。地址:https://github.com/NormanGyllenhaal/canal-client
引入依赖:
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
yml配置:
canal:
destination: heima # canal实例名称,要跟canal-server运行时设置的destination一致
server: 192.168.101.65:11111 # canal地址
3.2 监听器
编写监听器,监听Canal消息:
@CanalTable("tb_item") //要监听的表
@Component
public class ItemHandler implements EntryHandler<Item> {
@Override
public void insert(Item item) {
//写数据到jvm进程缓存
//写数据到redis
}
@Override
public void update(Item before, Item after) {
//写数据到jvm进程缓存
//写数据到redis
}
@Override
public void delete(Item item) {
//删除jvm进程缓存
//删除redis缓存
}
}
Canal推送给canal-client的是被修改的这一行数据(row),而我们引入的canal-client则会帮我们把行数据封装到Item实体类中。
这个过程中需要知道数据库与实体的映射关系,要用到JPA的几个注解: