Redis 双写一致性

本文讨论了如何通过Redis实现与MySQL数据的同步,强调双写一致性原则,并介绍使用读写锁(包括共享锁和排他锁)来确保数据强一致性,同时提到在特定场景下允许短暂不一致性和基于Canal的异步通知策略以提高性能。
摘要由CSDN通过智能技术生成

问题:redis 作为缓存,mysql 的数据如何与 redis 进行同步呢?(双写一致性)

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

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

什么是延迟双删?

  1. 先删除缓存,还是先修改数据库?

无论怎么操作都会存在数据不一致的问题。

  1. 为什么要删除缓存呢?

先删除缓存再删除数据库肯定是存在脏数据的,所以要删除两次缓存。

  1. 为什么要延时双删?

因为数据库是主从分离的,主从同步需要时间,所以需要延时删除。但是因为延时的时间不好控制,所以延时的过程中也可能出现脏数据

到底怎么才能保证数据的强一致性呢?

通过加锁的方式,但是性能比较低。
如何优化呢?
首先,存入缓存的数据一般都是读多写少,所以我们可以用读写锁控制。
共享锁:读锁 readLock,加锁之后,其他线程可以共享读操作。
排他锁:独占锁 writeLock 也叫,加锁之后,阻塞其他线程读写操作。
所以我们在读操作的时候可以加共享锁,其他线程就可以读,但是不可以写。

public item getById(Integer id){
	RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("ITEM_READ_WRITE_LOCK");
	// 读之前加读锁,读锁的作用就是等待该lockkey释放写锁以后再读
	RLock readLock = readWriteLock.readLock();
	try{
        // 开锁
        readLock.lock();
        System.out.println("readLock");
        Item item =(Item) redisTemplate.opsForValue().get("item:"+id);
        if(item != null){
            return item;
        }
        // 查询业务数据
        item = new Item(id,"华为手机","华为手机",5299.00);
        // 写入缓存
        redisTemplate.opsForValue().set("item:"+id,item);
        // 返回数据
        return item;
    }finally{
        readLock.unlock();
    }
}

在写操作的时候,加排他锁,其他线程都不能读写操作。

public void updateById(Integer id){
	RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("ITEM_READ_WRITE_LOCK");
	// 写之前加写锁,写锁加锁成功,读锁只能等待
	RLock writeLock = readWriteLock.writeLock();
	try{
        // 开锁
        writeLock.lock();
        System.out.println("writeLock");
        // 更新业务数据
        Item item = new Item(id,"华为手机","华为手机",5322.00);
        try{
            Thread.sleep(10000);
        }catch(InterruptedEXception e){
            e.printStackTrace();
        }
        // 删除缓存
        redisTemplate.delete("item:"+id);
    }finally{
        writeLock.unlock();
    }
}

使用读写锁肯定可以保证数据的强一致性,但是性能肯定低。所以需要保证数据强一致性的业务场景才会使用。

允许短暂的不一致性

  1. 异步通知保证数据的最终一致性

  1. 基于 Canal 的异步通知

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值