1、基于mq实现缓存同步
2、基于canal实现缓存同步

2.1 开启Mysql的主从
2.1.1 修改my.cnf,添加以下两行
log-bin=/morecache/mysql/mysql-bin
binlog-do-db=heima
重启docker,/mysql/data目录下会出现mysql-bin.000001
2.1.2 添加一个仅用于数据同步的账户
create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%' identified by 'canal';
FLUSH PRIVILEGES;
查看主库的状态(如果从库字段position小于主库,那么就有新的数据要获取了)
show master status
2.1.3 创建网络,让canal和mysql通信
docker network create heima
2.1.4 启动canal
docker run -p 11111:11111 --name canal \
-e canal.destinations=heima \
-e canal.instance.master.address=mysql:3306 \
-e canal.instance.dbUsername=canal \
-e canal.instance.dbPassword=canal \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false \
-e canal.instance.filter.regex=heima\\..* \
--network heima \
-d canal/canal-server:v1.1.5
当canal监听到binlog发生变化,会通知canal客户端。
2.1.5 引入依赖
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
2.1.6 编写yml配置
canal:
destination: heima # canal的集群名字,要与安装canal时设置的名称一致
server: 192.168.229.129:11111 # canal服务地址
2.1.7 编写监听canal
@CanalTable("tb_item") //监听的表
@Component
public class ItemHandler implements EntryHandler<Item> {
@Autowired
private RedisHandler redisHandler;
@Autowired
private Cache<Long, Item> itemCache;
@Override
public void insert(Item item) {
// 写数据到JVM进程缓存
itemCache.put(item.getId(), item);
// 写数据到redis
redisHandler.saveItem(item);
}
@Override
public void update(Item before, Item after) {
// 写数据到JVM进程缓存
itemCache.put(after.getId(), after);
// 写数据到redis
redisHandler.saveItem(after);
}
@Override
public void delete(Item item) {
// 删除数据到JVM进程缓存
itemCache.invalidate(item.getId());
// 删除数据到redis
redisHandler.deleteItemById(item.getId());
}
}
2.1.8 实体类
对于实体类,Canal会将改变的数据注入Item,如果属性名和数据库字段名不一致,需要用注解标明
@Data
@TableName("tb_item")
public class Item {
@TableId(type = IdType.AUTO)
@Id
private Long id;//商品id
@Column(name = "name")
private String name;//商品名称
private String title;//商品标题
private Long price;//价格(分)
private String image;//商品图片
private String category;//分类名称
private String brand;//品牌名称
private String spec;//规格
private Integer status;//商品状态 1-正常,2-下架
private Date createTime;//创建时间
private Date updateTime;//更新时间
@TableField(exist = false)
@Transient//不属于表内的字段
private Integer stock;
@TableField(exist = false)
@Transient
private Integer sold;
}