分布式缓存-简单易懂大白话

首先我们讲一下为什么要使用缓存?

通过空间换时间,加快速率,

什么时间使用缓存?

在数据库中不经常改变的。但是经常查询的进行缓存,例如:页面分类

为什么不使用本地缓存,本地缓存就相当于,如果缓存没有就封装在map(举例)中,本地进行缓存,这样的话,只可以在本项目中缓存,不可以进行清除,再一个就是不持久化。。。

这样使用到了分布式缓存,常用的分布式缓存有redis,mongodb

这里我们使用Redis

Redis可以搭建集群,主要有两种方式:哨兵和主从;

privateArrayList<CourseType>getCourseTypes() {
        List<CourseType>allCourseTypes=selectList(null);
        Map<Long, CourseType>collect=allCourseTypes.stream().collect(Collectors.toMap(CourseType::getId, t->t));
        ArrayList<CourseType>resultList=newArrayList<>();
​
        allCourseTypes.forEach(res->{
            /*如果没有Pid就直接放入List*/
            if (res.getPid()==null||res.getPid().equals(0L)){
                resultList.add(res);
            }else {
                /*如果有Pid就找父类*/
                CourseTypecourseType=collect.get(res.getPid());
                if (courseType!=null){
                    courseType.getChildren().add(res);
                }
            }
        });
//        hashMap.put(RedisConstants.COURSE_KEY,resultList);
        /*把查询到的数据缓存到Redis中*/
        redisTemplate.opsForValue().set(RedisConstants.COURSE_KEY,resultList);
        returnresultList;
    }
 /*Redis进行缓存*/
    @Override
    public List<CourseType> treeData() {
        List<CourseType> courseTypes = (List<CourseType>)redisTemplate.opsForValue().get(RedisConstants.COURSE_KEY);
        if (courseTypes!=null){
            return hashMap.get(RedisConstants.COURSE_KEY);
        }else {
            return getCourseTypes();
        }
​
    }

但是redis‘缓存存在这样存在一个问题(面试强调)

1.修改数据库的同时,修改reids中的数据(重置)会有短暂数据不一致
2.先删除redis中的数据,然后进行修改数据库,在高并发的情况下,可能正在修改数据库中数据的时候,又缓存之前的数据;
3. 延迟双删

先删除redis中的数据,在修改数据库

在修改数据库之后,再去删除redis数据

防止个别人,在我修改数据的时候,进行访问缓存我之前的数据

4.另外解决的一种办法

使用Alibaba的canal组件,它可以做数据库的同步操作。可以监听数据库的binary log日志,可以自动同步mysql或者其他的数据库的数据。

如果小伙伴不想导入新的组件,接下来我给大家手码:

重写三个方法

    @Override
    public boolean insert(CourseType entity) {
 
        boolean insert = super.insert(entity);
        if (insert){
//            /*插入成功之后删除Redis缓存中的数据,或者直接调用查询方法覆盖*/
//            redisTemplate.delete(RedisConstants.COURSE_KEY);
            getCourseTypes();
        }
        return insert;
    }
​
    @Override
    public boolean deleteById(Serializable id) {
        boolean b = super.deleteById(id);
        if (b){
            getCourseTypes();
        }
        return b;
    }
​
    @Override
    public boolean updateById(CourseType entity) {
        boolean b = super.updateById(entity);
        if (b){
            getCourseTypes();
        }
        return b;
    }
SpringCache注解缓存
  • @Cacheable:触发缓存写入。

  • @CacheEvict:触发缓存清除。

  • @CachePut:更新缓存(不会影响到方法的运行)。

  • @Caching:重新组合要应用于方法的多个缓存操作。

  • @CacheConfig:设置类级别上共享的一些常见缓存设置。

    @CacheEvict(cacheNames = RedisConstants.COURSE_KEY,key = "'all'")
    @Override
    public boolean insert(CourseType entity) {

        return super.insert(entity);

    }

    @Override
    @CacheEvict(cacheNames = RedisConstants.COURSE_KEY,key = "'all'")
    public boolean deleteById(Serializable id) {

        return super.deleteById(id);
    }

    @Override
    @CacheEvict(cacheNames = RedisConstants.COURSE_KEY,key = "'all'")
    public boolean updateById(CourseType entity) {

        return super.updateById(entity);

    }
    /*Redis进行缓存*/
    @Override
    @Cacheable(cacheNames = RedisConstants.COURSE_KEY,key = "'all'")
    public List<CourseType> treeData() {

        return getCourseTypes();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值