【大型电商项目开发】缓存-分布式锁-缓存一致性解决-45

导读:本篇文章讲解 【大型电商项目开发】缓存-分布式锁-缓存一致性解决-45,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一:缓存一致性

问题:缓存里面的数据如何和数据库当中的保持一致?

1.双写模式——数据库修改以后,将缓存中数据也修改一下

在这里插入图片描述
1)缺点:有可能产生脏数据。但是可以保证最终一致性。
2)解决方案:

  • 加锁
  • 暂时性数据不一致,为缓存数据加上过期时间

2.失效模式——删除掉缓存,等待下一次主动查询进行更新

在这里插入图片描述
1)缺点:会读到脏数据。第二个写如果进行的比较慢,就会导致第三个读,读到第一个写的脏数据
2)解决方案:

  • 经常修改的数据,就不要加入缓存了,直接放进数据库。

二:缓存一致性-解决方案

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

  • 1、如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加 上过期时间,每隔一段时间触发读的主动更新即可
  • 2、如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式。
  • 3、缓存数据+过期时间也足够解决大部分业务对于缓存的要求。
  • 4、通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心 脏数据,允许临时脏数据可忽略);

2.总结:

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

3.获取商品服务代码

public Map<String, List<Catalog2Vo>> getCatalogJsonFromDbWithRedissonLock() {
        //1.注入redisson,获取分布式锁。锁的名字,锁的粒度越细,速度越快
        //锁的粒度:具体缓存的是某个数据,11号商品
        RLock lock = redisson.getLock("catalogJson-lock");
        lock.lock();
        Map<String, List<Catalog2Vo>> dataFromDb = null;
        try {
            dataFromDb = getDataFromDb();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
           //释放锁
            lock.unlock();
        }
        return dataFromDb;
    }

三:缓存一致性-解决-Canal

Canal:阿里开源的中间件,可以模拟是一个数据库的从服务器。mysql有什么变化就会通过binlog二进制日志同步到cannal,canal会更新redis里的数据。
在这里插入图片描述
目前系统暂不使用canal,需要额外去维护。

四:我们系统一致性解决方案

1)缓存所有的数据都要有过期时间,数据过期下一次查询就能触发主动更新
2)读写数据的时候,加上分布式的读写锁

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84103.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!