Redis之缓存穿透,雪崩,击穿解读

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis之缓存穿透,雪崩,击穿解读

缓存穿透

定义

当我们请求去查询一条记录,先到redis中查询后到mysql查询都发现找不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增,这些请求像“穿透”了缓存一样直接打在数据库上,这种现象就叫做缓存穿透。这种现象我们称为缓存穿透,这个redis变成了一个摆设。

恶意对网站进行攻击时,拿一个不存在的id去查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉

解决方案

方案1:空对象缓存或者缺省值

一旦发生缓存穿透,我们就可以针对查询的数据,在Redis中缓存一个空值或是和业务层协商确定的缺省值(例如,库存的缺省值可以设为0) 。紧接着,应用发送的后续请求再进行查询时,就可以直接从Redis中读取空值或缺省值,返回给业务应用了,避免了把大量请求发送给数据库处理,保持了数据库的正常运行。

如果Redis查不到数据,数据库也查不到,我们把这个Key值保存进Redis,设置value="null",当下次再通过这个Key查询时就不需要再查询数据库。这种处理方式肯定是有问题的,假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。而且随着缓存的暑假的越来越多,对Redis的压力越来越大,可以对缓存的Key有个过期的时间分担压力。

方案2:布隆过滤器
  • 把已存在数据的key存在布隆过滤器中,相当于redis前面挡着一个布隆过滤器。
  • 当有新的请求时,先到布隆过滤器中查询是否存在:
  • 如果布隆过滤器中不存在该条数据则直接返回;
  • 如果布隆过滤器中已存在,才去查询缓存redis,如果redis里没查询到则再查询Mysql数据库

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。

一句话就是:由一个初始值为零的bit数组和多个哈希函数构成,用来快速判断集合中是否存在某个元素。

缓存击穿

定义

大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去(简单说就是热点key突然失效了,暴打mysql)。

造成缓存击穿的主要原因就是:我们为缓存中的数据设置了过期时间。如果在某个时刻从数据库获取了大量的数据,并设置了相同的过期时间,这些缓存的数据就会在同一时刻失效,造成缓存击穿问题

  1. 时间到了自然清除,但还被访问到了
  2. 删除key的时候,突然被访问到了

解决方案

方案1:热点数据永不过期

对于热点数据,如果业务允许的话,对于热点的key可以设置永不过期的key。

方案2:互斥独占锁防止击穿

使用分布式锁思想,保证对于每个 Key 同时只有一个线程去查询后端的服务,某个线程在查询后端服务的同时,其他线程没有获得分布式锁的权限,需要进行等待,查询到以后回写Redis,其他请求线程再到Redis中查询,当然这样会导致系统的性能变差。

示例java代码如下:

public User findUserById2(Integer id) {
    User user = null;
    String key = CACHE_KEY_USER+id;
    //1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql
    user = (User) redisTemplate.opsForValue().get(key);
    if(user == null) {
        //2 大厂用,对于高QPS的优化,进来就先加锁,保证一个请求操作,让外面的redis等待一下,避免击穿mysql
        synchronized (UserService.class){
            user = (User) redisTemplate.opsForValue().get(key);
            //3 二次查redis还是null,可以去查mysql了(mysql默认有数据)
            if (user == null) {
                //4 查询mysql拿数据
                user = userMapper.selectByPrimaryKey(id);//mysql有数据默认
                if (user == null) {
                    return null;
                }else{
                    //5 mysql里面有数据的,需要回写redis,完成数据一致性的同步工作
                    //setnx 不存在才创建
                    redisTemplate.opsForValue().setIfAbsent(key,user,7L,TimeUnit.DAYS);
                }
            }
        }
    }
    return user;
}

缓存雪崩

定义

缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库,还有一种情况是Redis主机挂了,Redis全盘崩溃

在某一时刻缓存集中失效,或者缓存系统出现故障,所有的并发流量就会直接到达数据库。数据存储层的调用量就会暴增,用不了多长时间,数据库就会被大流量压垮

解决方案

方案1:过期时间设置随机

在原有的失效时间上加上一个随机值,比如1-5分钟随机。这样就避免了因为采用相同的过期时间导致的缓存雪崩。

方案2:缓存预热

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

方案3:Redis集群

为了防止Redis宕机导致缓存雪崩的问题,可以搭建Redis集群,提高Redis的容灾性。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
7天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
15天前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
90 22
|
14天前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
103 7
|
18天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
52 10
|
存储 缓存 NoSQL
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
快速学习 Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
|
缓存 NoSQL 安全
6.0Spring Boot 2.0实战 Redis 分布式缓存6.0|学习笔记
快速学习6.0Spring Boot 2.0实战 Redis 分布式缓存6.0。
326 0
6.0Spring Boot 2.0实战 Redis 分布式缓存6.0|学习笔记
|
缓存 NoSQL Redis
首页数据显示-添加 redis 缓存(3)| 学习笔记
快速学习 首页数据显示-添加 redis 缓存(3)
150 0
首页数据显示-添加 redis 缓存(3)| 学习笔记
|
缓存 NoSQL Java
首页数据显示-添加 redis 缓存(1) | 学习笔记
快速学习 首页数据显示-添加 redis 缓存(1)
234 0
首页数据显示-添加 redis 缓存(1) | 学习笔记
|
存储 缓存 NoSQL
Redis 缓存|学习笔记
快速学习Redis 缓存
106 0