缓存里的数据如何和数据库的数据保持一致

缓存数据一致性
 1)、双写模式
 2)、失效模式

缓存数据一致性-双写模式

当两个线程同时去写数据库,由于卡顿等原因,导致写缓存2在最前,写缓存1在后面就出现了不一致。

这是暂时性的脏数据问题,但是在数据稳定,缓存过期以后,又能得到最新的正确数据 读到的最新数据有延迟:最终一致性。

缓存数据一致性-失效模式

 一致性解决方案:

1、缓存的所有数据都有过期时间,数据过期下一次查询触发主动更新。

2、读写数据的时候,加上分布式的读写锁。 经常写,经常读。

加上分布式的读写锁代码实现:

 保证一定能读到最新数据,修改期间,写锁是一个排它锁(互斥锁、独享锁),读锁是一个共享锁
 写锁没释放读锁必须等待。
 读 + 读 :相当于无锁,并发读,只会在Redis中记录好,所有当前的读锁。他们都会同时加锁成功。
 写 + 读 :必须等待写锁释放。
 写 + 写 :阻塞方式。
 读 + 写 :有读锁。写也需要等待。
 只要有读或者写的存都必须等待。

写数据的时候加上写锁实现代码:


        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("catalogJson-lock");
        //创建写锁
        RLock rLock = readWriteLock.writeLock();

        try {
            rLock.lock();
            this.baseMapper.updateById(category);
            categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rLock.unlock();
        }

        //同时修改缓存中的数据
        //删除缓存,等待下一次主动查询进行更新

读数据的时候加上读锁实现代码: 

        //1、占分布式锁。去redis占坑
        //(锁的粒度,越细越快:具体缓存的是某个数据,11号商品) product-11-lock
        //RLock catalogJsonLock = redissonClient.getLock("catalogJson-lock");
        //创建读锁
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("catalogJson-lock");

        RLock rLock = readWriteLock.readLock();

        Map<String, List<Catelog2Vo>> dataFromDb = null;
        try {
            rLock.lock();
            //加锁成功...执行业务
            dataFromDb = getDataFromDb();
        } finally {
            rLock.unlock();
        }
        //先去redis查询下保证当前的锁是自己的
    
        return dataFromDb;

 

缓存数据一致性-解决方案

无论是双写模式还是失效模式,都会导致缓存的不一致问题。即多个实例同时更新会出事。怎么办?

1、如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加 上过期时间,每隔一段时间触发读的主动更新即可

2、如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式。

3、缓存数据+过期时间也足够解决大部分业务对于缓存的要求。

4、通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心 脏数据,允许临时脏数据可忽略);

总结: 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保 证每天拿到当前最新数据即可。 我们不应该过度设计,增加系统的复杂性 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值