Redis学习-第四节-Redis应用问题与分布式锁

Redis应用问题

1.缓存穿透

1.1问题描述

key对应的数据不存在,每次获取该key的请求都获取不到缓存,导致数据库压力变大

1.2解决方案

(1)对空值缓存
  • 缓存空结果:如果一个查询结果为空,我们仍进行缓存,并且设置空结果的缓存过期时间会很短,一般不超过5分钟
  • 设置可访问的白名单:使用bitmaps类型定义一个白名单,名单id作为bitmaps的偏移量,每次访问和bitmaps里面的id进行比较,不存在进行拦截
  • 采用布隆过滤器
  • 实时监控:监控Redis缓存命中率,当缓存命中率极速降低时,需要排查访问对象和访问数据

2.缓存击穿

2.1问题描述

key对应数据已过期,当访问该key的大量并发请求发现数据过期,会去访问数据库获取数据,这些并发请求可能会导致数据库崩溃

2.2解决方案

  • 预先设置热门数据:在Redis访问高峰之前,预先缓存热门数据,并延长过期时间。
  • 实时调整:实时监控调整热门数据
  • 使用锁

3.缓存雪崩

3.1问题描述

在极短时间内,Redis内大量key过期失效,导致大量请求直接访问数据库,造成数据库崩溃

3.2解决方案

  • 构建多级缓存架构:nginx缓存+redis缓存+其他缓存(ehcache)
  • 使用锁或者队列:不适用于高并发
  • 设置过期标志更新缓存:记录缓存数据是否过期,当数据过期触发通知,通知另外的线程去更新key的值
  • 将缓存失效的时间分散开:缓存失效的时间基础上添加随机值,使过期时间分散开

Redis分布式锁

1.问题描述

随业务发展需要,由原先的单机部署系统主键演变为分布式部署,导致原单机部署时的并发控制锁策略失效,就衍生出了分布式锁。

2.分布式锁主流实现方案

(1)基于数据库
(2)基于Redis(性能最高)
(3)基于Zookeeper(可靠性最高)

3.基于Redis实现分布式锁

(1)使用setnx命令上锁
(2)使用del命令释放锁
(3)使用expire命令设置自动释放锁的时间
(4)前三组合命令:set key value nx ex 过期时间

4.锁被误释放

4.1问题描述

服务a上锁,设置过期时间,在处理业务逻辑时,锁过期自动释放。服务b上锁,服务a业务逻辑处理完成,释放锁时,将服务b的锁误释放。

4.2解决方案

使用uuid作为锁的值,每次释放锁,进行uuid的比较,比较通过后才会释放锁,并且锁释放操作使用LUA脚本,保证原子性

public void testLock(){

        String uuid = UUID.randomUUID().toString();

        //1.获取锁
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid,3, TimeUnit.MILLISECONDS);

        if (lock){
            Object value = redisTemplate.opsForValue().get("num");

            //判断num是否为空
            if (StringUtils.isEmpty(value)){
                return;
            }

            //有值转换为int
            int num = Integer.parseInt(value+"");
            //把redis的num值+1+
            redisTemplate.opsForValue().set("num",++num);
            //释放锁
            String lockUuid = (String) redisTemplate.opsForValue().get("lock");
            if (uuid.equals(lockUuid)){
                redisTemplate.delete("lock");
            }
        }else {
            try {
                Thread.sleep(100);
                testLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

5.分布式锁可用四大条件

(1)互斥性:同一时间,只能有一个用户持有锁
(2)不会发生死锁:即持有锁的客户端哪怕是崩溃也会释放锁(设置锁自动过期时间)
(3)加锁和释放锁必须是同一个用户(使用uuid)
(4)加锁和释放锁的操作保证原子性(lua脚本)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值