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();
    }
}
相关推荐
BillKu5 分钟前
Java核心概念详解:JVM、JRE、JDK、Java SE、Java EE (Jakarta EE)
java·jvm·jdk·java ee·jre·java se·jakarta ee
刘婉晴1 小时前
【Java】NIO 简单介绍
java·nio
渣哥1 小时前
聊聊我和 ArrayList、LinkedList、Vector 的“一地鸡毛”
java
浮游本尊1 小时前
Java学习第20天 - 性能优化与监控
java
纪莫2 小时前
技术面:Java并发(线程同步、死锁、多线程编排)
java·java面试⑧股
衍余未了2 小时前
k8s 内置的containerd配置阿里云个人镜像地址及认证
java·阿里云·kubernetes
叽哥2 小时前
Kotlin学习第 4 课:Kotlin 函数:从基础定义到高阶应用
android·java·kotlin
渣哥2 小时前
使用 HashMap 提高性能的小技巧
java
kyle~2 小时前
排序---快速排序(Quick Sort)
java·开发语言
小蒜学长2 小时前
旅行社旅游管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·旅游