首页 > 数据库 >Redis 击穿、穿透、雪崩产生原因以及解决思路

Redis 击穿、穿透、雪崩产生原因以及解决思路

时间:2024-01-18 11:34:42浏览次数:23  
标签:key 请求 过期 Redis 数据库 击穿 雪崩 Key

Redis 击穿、穿透、雪崩产生原因以及解决思路

路人 Java充电社 2024-01-18 08:06 发表于上海

您好,我是路人,更多优质文章见个人博客:http://itsoku.com

前言

大家都知道,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生了缓存,将一些热点数据放在内存中,随用随取,降低连接到数据库的请求链接,避免数据库挂掉。需要注意的是,无论是击穿还是后面谈到的穿透与雪崩,都是在高并发前提下,比如当缓存中某一个热点key失效。

image

问题起因

有两个主要原因:

1、Key过期;
2、Key被页面置换淘汰。

对于第一个原因是因为在Redis中,Key有过期时间,如果某一个时刻(假如商城做活动,零点开始)key失效,那么零点之后对某一个商品查询请求将全都压到数据库上,导致数据库崩。

对于第二个原因,因为内存是有限的,要时时刻刻缓存新的数据,淘汰旧的数据,所以在一定的页面置换策略(常见页面置换算法图解)中,淘汰数据,如果某些商品做活动之前无人问津,势必会被淘汰。

应对击穿的处理思路

正常的处理请求如图:

image

由于key过期在所难免,高流量来到Redis时,根据Redis的单线程特性,可以认为任务是在队列里依次执行的,当请求到达Redis发现Key过期时,进行一个操作:设置锁。

这个流程大概如下:

  1. 请求到达Redis,发现Redis Key过期,查看有没有锁,没有锁的话回到队列后面排队
  2. 设置锁,注意,这儿应该是setnx(),而不是set(),因为可能有其他线程已经设置锁了
  3. 获取锁,拿到锁了就去数据库取数据,请求返回后释放锁。

image

但是引出了一个新的问题,如果拿到锁去拿数据的请求然后挂了怎么办?也就是锁没有释放,其他进程都在等锁,解决办法是:

对锁设置一个过期时间,如果到达了过期时间还没释放就自动释放,问题又来了,锁挂了好说,但是如果是锁超时呢?也就是在设定的时间里数据没有取出来,但是锁由过期了,常见的思路是,锁过期时间值递增,但是想想不靠谱,因为第一个请求可能超时,如果后面的也超时呢,接连多次超时之后,锁过期时间值势必特别大了,这样做弊端太多。

另外一个思路是,再开启一个线程,进行监控,如果取数据的线程没有挂的话,就适当延迟锁的过期时间。

image

穿透

穿透主要原因是很多请求都在访问数据库不存在的数据,例如一个卖书的商城一直被请求查询茶叶产品,由于Redis缓存主要是用来缓存热点数据,对于数据库都不存在的数据,是没法缓存的,这种异常流量就会直接到达数据库并且返回"没有"的查询结果。

应对这种请求,处理办法是对访问请求加一层过滤器,例如布隆过滤器、增强版布隆过滤器、布谷鸟过滤器,详情见:Redis布隆过滤器与布谷鸟过滤器。

image

除了布隆过滤器,可以增加一些参数检验,例如数据库数据id一般都是递增的,如果请求 id = -10 这种参数,势必绕过Redis,避免这种情况,可以对用户真实性检验等操作。

雪崩

雪崩,和击穿类似,不同的是击穿是一个热点Key某时刻失效,而雪崩是大量的热点Key在一瞬间失效,网络上很多博客都在强调解决雪崩的策略是随机过期时间,这个非常不准确,举个例子,银行做活动,之前这个利息系数为2%,过了零点系数改为3%,这种情况能将用户的对应的key改为随机过期吗?如果用的过去的数据叫脏数据。

明显不可以,同样存钱,你存到年底利息300万,隔壁才200万,这不得打架啊,开玩笑~

正确的思路是,首先要看看这个Key过期是不是时点性有关,时点性无关的话,可以随机过期时间解决。

如果是时点性有关,例如刚刚说的银行某一天改变某系数,那么就要利用强依赖击穿方案,策略是先过去的线程更新一下所有key。

image

在后台更新热点key的同时,业务层将进来的请求延时一下,例如短暂的睡几毫秒或者秒,给后面的更新热点key分散压力。

标签:key,请求,过期,Redis,数据库,击穿,雪崩,Key
From: https://www.cnblogs.com/hefeng2014/p/17972152

相关文章

  • 工作中使用Redis的10种场景
    前言Redis作为一种优秀的基于key/value的缓存,有非常不错的性能和稳定性,无论是在工作中,还是面试中,都经常会出现。今天这篇文章就跟大家一起聊聊,我在实际工作中使用Redis的10种场景,希望对你会有所帮助。1.统计访问次数对于很多官方网站的首页,经常会有一些统计首页访问次数的需......
  • Redis系列:使用 Redis Module 扩展功能
    ★Redis24篇集合1啥是RedisModuleRedisModule是Redis的一种扩展模块,从4.0版本开始,允许用户自定义扩展模块,在Redis内部实现新的数据类型和功能,使用统一的调用方式和传输协议格式扩展Redis的能力。它本身的设计目的就是在不同版本的Redis中运行,因此无需重新编译模块即可与特......
  • redis高可用哨兵篇
    https://redis.io/docs/manual/sentinel/#sentinels-and-replicas-auto-discovery官网资料在上文主从复制的基础上,如果注节点出现故障该怎么办呢?在Redis主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的问题。哨兵机制(RedisSen......
  • redis自动化安装
    1.ruby脚本自动化安装1.安装ruby开发环境yuminstallrubygems-y2.通过ruby包管理工具,安装操作redis的模块gemsources--removehttps://rubygems.org/gemsources--removehttp://mirrors.aliyun.com/rubygems/gemsources-ahttps://mirrors.cloud.tencent.com/ru......
  • redis实战技巧
    1.分析key大小[root@db-51~]#redis-cli-h10.0.0.51-p6380--bigkeys#Scanningtheentirekeyspacetofindbiggestkeysaswellas#averagesizesperkeytype.Youcanuse-i0.1tosleep0.1sec#per100SCANcommands(notusuallyneeded).--------......
  • redis数据持久化篇
    为什么需要持久化Redis是个基于内存的数据库。那服务一旦宕机,内存中的数据将全部丢失。通常的解决方案是从后端数据库恢复这些数据,但后端数据库有性能瓶颈如果是大数据量的恢复,1、会对数据库带来巨大的压力,2、数据库的性能不如Redis。导致程序响应慢。所以对Redis来说,实现数......
  • redis安全篇
    redis被攻击,作为突破口,服务器惨遭毒手的事太常见了。大多数云服务器被攻击,都是redis,mongodb等数据库被入侵。因此修改端口,密码,以及注意bind运行地址,是必须。思考是否要暴露redis到公网。1.设置密码、端口配置[root@db-51~]#cat/opt/redis_6379/conf/redis_6379.confdae......
  • 从python 单机版爬虫 scrapy 到 分布式scrapy-redis 爬虫用最简单的步骤创建实例
    scrapy是很强大的模块化爬虫框架,具有很高的灵活性,使用频率很高,使用该框架能大大提高开发效率,scrapy-redis是在scrapy框架开发了组件,替换队列部分,实现多台服务器并行运行爬虫,提高爬取速度。下面是用最简单的例子从建立普通scrapy爬虫,然后数据保存mysql,最后简单替换几行就能使用s......
  • Redis - Search
                        ......
  • Redis实战篇
    实战篇Redis优秀博客黑马点评项目学习笔记(15w字详解,堪称史上最详细,欢迎收藏)-CSDN博客Redis实战篇|Kyle'sBlog(cyborg2077.github.io)开篇导读hutol工具使用对象bean和JsonStr互转//功能:javabean转jsonstr用途:存入到redisStringjsonstr=JSONUtil.toJsonSt......