redis之缓存穿透击穿雪崩问题与缓存删除淘汰策略(代码片段)

丨Jack_Chen丨 丨Jack_Chen丨     2022-12-02     793

关键词:

一、缓存问题与解决

缓存穿透

缓存穿透是指查询缓存和DB中都不存在的数据

缓存穿透示例:

    public Station findProjectStation(Long stationId) 
        //从缓存中查询
        Station station = (Station)redisTemplate.boundHashOps("project_station").get(stationId);
        if(station==null)
            //缓存中没有,从数据库查询
            Station st = stationMapper.selectByPrimaryKey(stationId);
            if(st!=null) 
                station = st;
                redisTemplate.boundHashOps("project_station").put(stationId,station);
            
        
        return station;
    

解决方案:

​1.接口层增加校验,如鉴权校验

2.id做校验,id<=0的直接拦截;

​3.从缓存取不到的数据,在数据库中也没有取到,就将key-value对写为key-空对象。以此防止攻击者反复用同一个id暴力攻击。

4. 使用缓存预热,缓存预热就是将数据提前加入到缓存中,当数据发生变更,再将最新的数据更新到缓存。

5. 利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试

6. 利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回

解决缓存穿透示例:

    public Station findProjectStation(Long stationId) 
        //从缓存中查询
        Station station = (Station)redisTemplate.boundHashOps("project_station").get(stationId);
        if(station==null)
            //缓存中没有,从数据库查询
            Station st = stationMapper.selectByPrimaryKey(stationId);
            if(st!=null)
                station = st;
                redisTemplate.boundHashOps("project_station").put(stationId,station);
            else 
                redisTemplate.boundHashOps("project_station").put(stationId,new Station());
                redisTemplate.boundHashOps("project_station").expire(60, TimeUnit.SECONDS);
            
        
        return station;
    

缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据

可能产生缓存击穿示例:

    public List<Station> findStationList() 
        //从缓存中查询
        List<Station> stationList = (List<Station>)redisTemplate.boundValueOps("station_list").get();;
        if(stationList==null)
            //缓存中没有,从数据库查询
            Example example=new Example(Station.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("type","1");
            List<Station> findStationList = stationMapper.selectByExample(example);
            if(findStationList!=null)
                stationList = findStationList;
                redisTemplate.boundValueOps("station_list").set(stationList);
            
        
        return stationList;
    

解决方案:

​1.设置热点数据永远不过期。

​2.缓存预热

3.数据不设置过期时间,在缓存的对象上添加一个属性标识过期时间,每次获取到数据时,校验对象中的过期时间属性,如果数据即将过期,则异步发起一个线程主动更新缓存中的数据,当然也可能拿到过期的值,看具体需求。

缓存雪崩

缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机

解决方案:

​1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题

​2.设置热点数据永远不过期。

​3.使用缓存预热

4.使用互斥锁,但是该方案将导致吞吐量明显下降

三者区别

缓存穿透:通常请求携带有参数,不断发起请求。

缓存击穿:通常是某个时刻并发大量请求,并发查询同一条数据。

缓存雪崩:缓存不同的数据大批量到过期时间,很多数据都查不到从而查数据库。

缓存预热

实现缓存预热方法:

@Component
public class RedisInit implements InitializingBean

@Autowired
private IStationService stationService;

/**
 * 缓存预热
 *
 * @throws Exception
 */
@Override
public void afterPropertiesSet() throws Exception 
    stationService.saveStationListToRedis();



# 二、缓存淘汰机制
>Redis可以对存储在Redis中的缓存数据设置过期时间,但是并非key过期时间到了就一定会被Redis给删除。

Redis可以设置最大缓存即最大内存,当内存已使用率到达,则开始清理缓存

    maxmemory <bytes> :设置最大内存 maxmemory 500mb
## 删除策略
>设置了expire的key缓存过期了,但是服务器的内存还是会被占用,这是因为redis是基于删除策略进行删除

Redis删除策略主要有三种:

1.定期删除

>Redis默认是每隔 100ms 就随机抽取一些设置了过期时间的 Key,检查其是否过期,如果过期就删除。

2.惰性删除

>定期删除由于是随机抽取可能会导致很多过期 Key 到了过期时间并没有被删除。在从缓存获取数据的时候,redis会检查这个key是否过期了,如果过期就删除这个key。也就是说在查询的时候将过期key从缓存中清除。

3.主动删除

>当内存满了,依据配置的淘汰策略进行删除

## 内存淘汰机制
>仅使用定期删除 + 惰性删除机制存在一个严重的隐患:如果定期删除留下了很多已经过期的key,并且长时间都没有使用过这些过期key,会导致过期key无法被惰性删除,从而导致过期key一直堆积在内存里,最终造成Redis内存块被消耗殆尽。

Redis内存淘汰机制应运而生。Redis内存淘汰机制提供了八种不同的内存淘汰策略,4.0前有6种。

    volatile-lru : 从已设置过期时间的缓存中,淘汰最近最少使用的数据,推荐使用策略

    volatile-ttl: 在设置了过期时间的缓存中,挑选将要过期的数据,直接淘汰

    volatile-random: 从已设置过期时间的缓存中,随机淘汰数据

    allkeys-lru: 所有数据,淘汰最近最少使用的,即清除最少用的旧缓存,然后保存新的缓存,推荐使用

    allkeys-random: 在所有的缓存中随机删除,不推荐

    noeviction: 旧缓存永不过期,新缓存设置不了,不淘汰,内存满了返回错误,默认策略

    volatile-lfu: 从已设置过期时间的缓存中,淘汰使用频率最低的数据

    allkeys-lfu: 所有数据,淘汰使用频率最低的数据

redis淘汰策略与过期策略及其应用场景

...策略Redis的过期策略那么我们应如何合理的设置过期时间缓存穿透、缓存击穿、缓存雪崩有什么区别,该如何解决?缓存穿透:问题描述:解决方案:缓存击穿:问题描述:解决方案:缓存雪崩࿱... 查看详情

redis淘汰策略与过期策略及其应用场景

...策略Redis的过期策略那么我们应如何合理的设置过期时间缓存穿透、缓存击穿、缓存雪崩有什么区别,该如何解决?缓存穿透:问题描述:解决方案:缓存击穿:问题描述:解决方案:缓存雪崩࿱... 查看详情

redis的缓存问题之缓存穿透缓存雪崩缓存击穿(代码片段)

目录一、什么是缓存穿透?二、常见的解决方案有两种:1、缓存空对象2、布隆过滤综上所述三、编码解决商品查询的缓存穿透问题四、缓存雪崩问题及解决思路1、什么是缓存雪崩?五、缓存击穿问题及解决思路 1、... 查看详情

redis的缓存穿透缓存雪崩缓存击穿问题的概念与解决办法(代码片段)

详细介绍了Redis的缓存穿透、缓存雪崩、缓存击穿等问题的概念与解决办法。文章目录1缓存穿透1.1什么是缓存穿透?1.2怎么解决1.3BloomFilter布隆过滤器1.3.1BloomFilter的原理1.3.2BloomFilter的优缺点1.3.3GuavaBloomFilter1.3.4RedisBloomFilter2... 查看详情

redis缓存穿透击穿雪崩到底是个啥?7张图告诉你(代码片段)

目录一、缓存是什么?二、缓存的作用和成本1、缓存的作用:2、缓存的成本:三、缓存作用模型1、根据id查询数据缓存流程四、缓存更新策略1、内存淘汰2、超时剔除3、主动更新五、缓存穿透解决方法:六、缓... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

文章目录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

文章目录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式... 查看详情

redis缓存雪崩缓存穿透缓存击穿

Redis缓存雪崩、缓存穿透、缓存击穿Redis缓存过程缓存雪崩解决方案永不过期合理的设置过期时间使用Redis的分布式锁缓存穿透解决方案过滤非法查询缓存空对象布隆过滤器布隆过滤器的新增布隆过滤器的查询布隆过滤器的删除布... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis08_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

缓存雪崩击穿穿透

   缓存雪崩:   为了保证缓存中的数据与数据库中的数据一致性,会给Redis里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库... 查看详情

如何解决redis缓存雪崩击穿与穿透(代码片段)

Redis最常用使用的场景就是作为业务系统的缓存,既然是作为缓存,那么就不免会碰到缓存常见的问题,即雪崩、击穿与穿透,什么是缓存雪崩、击穿与穿透以及如何解决这几个问题呢?今天我们一起来探讨一... 查看详情

redis缓存穿透缓存击穿缓存雪崩的原理和解决办法(代码片段)

Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法1.前言2.缓存穿透的解决办法3.缓存击穿解决办法4.缓存雪崩的解决办法1.前言在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的压力,缓... 查看详情

redis缓存穿透缓存击穿缓存雪崩的原理和解决办法(代码片段)

Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法1.前言2.缓存穿透的解决办法3.缓存击穿解决办法4.缓存雪崩的解决办法1.前言在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的压力,缓... 查看详情

redis从入门到进阶第6讲:缓存雪崩击穿穿透场景与解决方案(代码片段)

...的数据类型开始记录,直到一些更多的应用,如缓存击穿还有分布式锁以及Redis持久化等。希望大家有问题也可以一起沟通,欢迎一起学习,对于专栏内容有错还望您可以及时指点,非常感谢大家🌹。目录... 查看详情

redis系列缓存击穿穿透雪崩解决方案详解

...#xff0c;为了解决内存与磁盘速度不匹配的问题,产生了缓存,将一些热点数据放在内存中,随用随取,降低连接到数据库的请求链接,避免数据库挂掉。需要注意的是,无论是击穿还是后面谈到的穿透与雪... 查看详情

redis缓存穿透缓存击穿缓存雪崩(面试必备)

啥也不说了,面试高频问题。一、缓存穿透用户想要查询一个数据,发现redis内存数据库中没有,也就是说没有命中缓存,也是会向持久层数据库查询,发现也没有,那么本次查询失败。如果此时,用户很多,高并发场景下都去... 查看详情