Mysql的数据如何与redis进行同步(双写一致性)

双写一致性:

当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致。

  • 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,返回数据。
  • 写操作:延迟双删。

删除缓存 ----> 修改数据库 --延时--> 删除缓存
① 为什么要删除两次缓存? 为了减少脏数据的出现。
② 为什么要延时双删? 一般数据库为主从模式,是读写分离的,需要延时一会等数据从主节点同步到从节点。
③ 延时双删有什么问题?

  1. 延时时间不太好确定。
  2. 延时的过程中可能会出现脏数据。

使用异步方案同步数据(最终一致性)

  • 使用MQ中间件,更新数据之后,通知缓存删除。
  • 利用canal中间件,不需要修改业务代码,伪装为MySQL的一个从节点,canal通过读取binlog数据更新缓存。

使用读写锁同步(强一致性)

  • 采用Redisson提供的读写锁。
kotlin 复制代码
// 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作。
//读操作
public Object getById(Long id){
    RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("TEST_LOCK");
    // 读锁
    RLock readLock = readWriteLock.readLock();
    try{
        readLock.lock();
        System.out.println("readLock...");
        Object result = (Object) redisTemplate.opsForValue().get("goods:" + id);
        if (result != null){
            return result;
        }
        //  数据库查询
        result = goodsMapper.selectGoodsByGoodsId(id);
        // 写入缓存
        redisTemplate.opsForValue().set("goods:" + id, result);
        return result;
    }finally {
        readLock.unlock();
    }
}
csharp 复制代码
// 排他锁:独占锁writeLock,加锁之后,阻塞其他线程读写操作。
// 写操作
public void updateById(Goods goods){
    RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("TEST_LOCK");
    // 写锁
    RLock writeLock = readWriteLock.writeLock();
    try{
        writeLock.lock();
        System.out.println("writeLock...");
        // 更新数据库
        goodsMapper.updateById(goods);
        try {
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        // 删除缓存
        redisTemplate.delete("goods:" + goods.getGoodsId());
    }finally {
        writeLock.unlock();
    }
}
相关推荐
王桑.16 分钟前
IO流高级流--转换流
java
qq_124987075339 分钟前
基于SpringBoot技术的企业请假审批管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·信息可视化·毕业设计
BBB努力学习程序设计1 小时前
Java方法详解:提升代码复用性与可读性的利器
java
BBB努力学习程序设计1 小时前
Java运算符完全指南:让代码学会“计算”和“判断”
java
用户84913717547161 小时前
ThreadLocal 源码深度解析:JDK 设计者的“妥协”与“智慧”
java·后端
用户0304805912632 小时前
# 【Maven避坑】源码去哪了?一文看懂 Maven 工程与打包后的目录映射关系
java·后端
v***55342 小时前
springboot使用logback自定义日志
java·spring boot·logback
qq_336313932 小时前
java基础-集合进阶
java·开发语言·windows
稚辉君.MCA_P8_Java2 小时前
Gemini永久会员 归并排序(Merge Sort) 基于分治思想(Divide and Conquer)的高效排序算法
java·linux·算法·spring·排序算法
q***18842 小时前
Spring Boot中的404错误:原因、影响及处理策略
java·spring boot·后端