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();
    }
}
相关推荐
一定要AK22 分钟前
Spring 入门核心笔记
java·笔记·spring
A__tao23 分钟前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao36 分钟前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
迷藏49442 分钟前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
wuxinyan1232 小时前
Java面试题47:一文深入了解Nginx
java·nginx·面试题
新知图书2 小时前
搭建Spring Boot开发环境
java·spring boot·后端
冰河团队2 小时前
一个拉胯的分库分表方案有多绝望?整个部门都在救火!
java·高并发·分布式数据库·分库分表·高性能
洛_尘2 小时前
Java EE进阶:Linux的基本使用
java·java-ee
宸津-代码粉碎机2 小时前
Spring Boot 4.0虚拟线程实战调优技巧,最大化发挥并发优势
java·人工智能·spring boot·后端·python
MaCa .BaKa2 小时前
47-心里健康咨询平台/心理咨询系统
java·spring boot·mysql·tomcat·maven·intellij-idea·个人开发