Redis 缓存一致性

Redis 业务结构

在这里插入图片描述
流程图

在这里插入图片描述

缓存一致性

Redis 和 MySQL 中数据保持一致

双检加锁策略

主要用于解决多线程环境下的并发问题,确保在高并发场景下对共享资源的访问是互斥的,避免因竞争条件导致的不一致状态

public User findUserById(Integer id) {
	User user = null;
	String key = CACHE_KEY_USER + id;
	
	user = (User) redisTemplate.opsForValue().get(key);
	if (user == null) {
		// 处理缓存击穿
		synchronized (UserService.class) {
			user = (User) redisTemplate.opsForValue().get(key);
			if (user == null) {
				user = userMapper.selectByPrimaryKey(id);
				if (user == null) {
					// 缓存null,处理缓存穿透
					redisTemplate.opsForValue().setIfAbsent(key, null, 7L, TimeUnit.DAYS);
				} else {
					// mysql里面有数据的,需要回写redis,完成数据一致性的同步工作
					redisTemplate.opsForValue().setIfAbsent(key, user, 7L, TimeUnit.DAYS);
				}
			}
		}
	}
	return user;
}

缓存都要设置超时时间的原因

因为业务一般以MySQL的数据为准,给缓存设置过期时间,定期清理,可以保证最终一致性

缓存一致性的实现

延时双删
先删除缓存 + 更新数据库 + 再删除缓存

分布式锁
保证只有一个线程能持有资源,避免数据不一致

异步通知
canal ,监控mysql binlog,当bin log更新时,同步到redis

MySQL主从复制原理

在这里插入图片描述

canal 工作原理

1、canal 模拟MySQL 交互协议,把自己伪装成 slave
2、canal 读取到 mysql 的bin log 并解析
3、执行自定义操作,如 对Redis 进行相同的变更

canal 缓存一致性实践

添加主从用户

MySQL添加 canal 用户,(测试也可以直接使用 root用户)

DROP USER IF EXISTS 'canal'@'%';
create user 'canal'@'%' identified by 'canal';
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';
ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';
FLUSH PRIVILEGES;

修改MySQL配置文件

修改MySQL配置文件,开启 bin_log
my.cnf

在这里插入图片描述

下载 canal

docker pull canal/canal-server

启动 canal

从镜像获取配置文件 => 修改配置文件 => 开启新镜像

# 第一遍 不挂载 获取配置文件
docker run -p 11111:11111 --name canal -d canal/canal-server:latest


# 复制配置文件
docker cp df67a55b855d:/home/admin/canal-server/conf/example/instance.properties  /usr/local/canal/conf/

# 删除原来的容器 
docker rm $(doc ker stop canal)

# 挂载启动新容器
docker run -p 11111:11111 --name canal \
-v /usr/local/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-d canal/canal-server:latest

通过日志查看 canal 服务状态

如果出问题,这里可以看到信息

docker exec -it canal /bin/bash

tail -f /home/admin/canal-server/logs/example/example.log
在这里插入图片描述

配置 canal

在这里插入图片描述

1、这里的 canal.instance.mysql.slaveId 与 前面 MySQL配置的server_id 不同即可

2、master.address 填 mysql 地址

3、canal 连接 mysql的账密

4、canal 监控的 mysql 库表

5、这里的canal.mq、topic 对应后续代码实践的 destination

在这里插入图片描述 在这里插入图片描述

Java 业务代码

gitee 业务代码

canal 效果演示

建表

CREATE TABLE `t_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `userName` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4

插入数据前

在这里插入图片描述

MySQL 插入数据

insert into bigdata.t_user VALUES (1, 'zhangsan'), (2, 'lisi');

业务代码监控

在这里插入图片描述

插入数据后

在这里插入图片描述

bin log 内容查看

show variables like 'log_bin';

在这里插入图片描述

show binary logs;

在这里插入图片描述

show master status;

在这里插入图片描述

show binlog events in 'mysql-bin.000006';
在这里插入图片描述

返回值字段说明:

  • Log_name:查询的binlog文件名
  • Pos:pos起始位置
  • Event_type:事件类型
  • Server_id:服务器ID,my.cnf 进行设置
  • End_log_pos:pos结束点
  • Info:日志说明
  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值