NoSQL:Redis缓存、雪崩、击穿、穿透
Redis介绍
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1]
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
Redis的官网地址,非常好记,是Redis.io。(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地),Vmware在资助着redis项目的开发和维护。
Redis持久化分为RDB和AOF:
RDB:RDB是在指定时间内将数据根据快照保存在磁盘中,在磁盘中会生成一个二进制文件。
RDB触发机制分为Save和bgServe:
Save:他会将Redis进行阻塞只有执行完之后其他操作才可以执行,他会将原先的旧文件替换掉
bgSave:Redis会异步执行快照,在执行快照期间也可以进行其他操作。
AOF:AOF是将每一个写的操作最佳到文件后面,就相当于日志记录一样。
AOF:触发always、everysec、no
always:每次数据发生改变的时候进行保存
everysec:每秒同步
no:从不同步
Redis缓存
分布式缓存解决的问题:数据库服务器和Web服务器之间的瓶颈,如果一个网站流量很大这个瓶颈会非常明显,每次数据库查询耗费的时间讲Velocity来实现页面静态化。对于更新数据已秒级的站点,静态化也不会立项,可通过分布式缓存系统来解决,如Redis数据存储方案
Redis雪崩、穿透、击穿
一、雪崩
1.通俗场景
双十一期间,所有用户一打开淘宝就是进入首页,首页的压力非常大,为了提高并发,将网站数据都缓存到Redis里,所有的Redis Key失效时间都是3小时。双十一当天大量用户剁手狂欢,这时候3小时过去了,Redis里首页的key缓存全部失败,这时候Redis里查询不到数据了,只能去数据中查询,造成数据库无法响应挂掉
总结
雪崩指的十多个key查询并且出现高并发,缓存中失效或查不到,然后都去DB查询,从而导致DB突然飙升,从而导致数据库崩溃
出现原因
(1)key同时失效
(2)Redis本身崩溃了
2.雪崩解决方案
1)加锁排队
加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。加色在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都阻塞的。同样会导致用户等待超时,这是个治标不治本的方法!
注意:加锁排队的解决方式分布式环境的高并发问题,有可能还要解决分布式锁的问题;线程还会被阻塞,用户体验很差!因此,在真正的高并发场景下很少使用!
2)缓存失效时间分散开(随机值)
setRedis(key,value,time+Math.random()*10000)
为不同的key设置随便不同的时间,避免大量的key同时失效
二、击穿
1.通俗场景
任用脚本疯狂的给老哥发送请求,查询id=-1的数据,Redis并没有这样的数据,这时候就击穿redis,直接打到数据库上。
当缓存与数据库中都不存在该数据上时,由于当数据库查询不到数据就不会写入缓存,这个时候如果用户不断的恶意发送请求,就会导致这个不存在的数据每次请求都会查询DB,请求量打的情况下,就会导致DB压力过大,直接挂掉
总结
Redis中没有这样的数据,无法进行拦截,直接被穿透到数据库,导致数据库压力过大宕机。
2.解决方案
可以先过滤请求不合法数据(如数据库id都是大于o的,结果你一直用小于o的去请求,这就不合法)
1)缓存空数据
当查询返回一个空数据时,直接将这个空数据存到缓存中,过期时间不宜设置过长,建议不超过s分钟
2)采用布隆过滤器
布隆过滤器(Bloom Filter):是由Howard Bloom在1970年提出的一种比较巧妙的概率型数据结构,它可以告诉你某种东西一定不存在或者可能存在
将所有可能存在数据,分别通过多个哈希函数生成多个哈希值,然后将这些哈希值存到一个足够大的bitmap中,此时一个一定不存在的数据就会被这个bitmap拦截,从而减少了数据库的查询压力。
bf.add:添加元素到布隆过滤器中,类似于集合的sadd命令,不过bf.add命令只能—次添加一个元素,如果想—次添加多个元素,可以使用bf.madd命令。
bf.exists:判断某个元素是否在过滤器中,类似于集合的sismember命令,不过bf.exists命令只能一次查询一个元素,如果想—次查询多个元素,可以使用bf.mexists命令。
布隆器原理:
Redis中布隆过滤器的数据结构就是一个很大的位数组和几个不一样的无偏哈希函数(能把元素的哈希值算得比较平均,能让元素被哈希到位数组中的位置比较随机)
三、击穿
1、通俗场景
双十一马爸爸突发奇想,想拍卖自己穿了20年的老布鞋,并且附带本人签名,程序员将该鞋的信息存到了redis中,设置了3小时过期。寻思3小时够他们抢了吧,但他低估了马爸爸的魅力。该商品引起了一千万人关注,这些人不断的竞拍这双鞋,价格越拍越高,马爸爸乐开了花。竞拍了2小时59分,马上要拍到一个亿了,突然这双鞋在redis里的key数据过期了,导致该key的大量请求,都打到了数据库,直接导致数据库挂掉了,服务无法响应。
key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮
总结
某一个热点key,在不停地扛着高并发,当这个热点key在失效的一瞬间,持续的高并发访问就击破缓存直接访问数据库,导致数据库宕机
*与雪崩的区别:雪崩是一堆key过期请求,击穿中指高并发对一个无效的key请求*
2、解决方案
1)设置热点数据"永不过期"加上
2)加上互斥锁
上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用—个互斥锁来锁住它
其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到redis缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存
雪崩是大面积的key缓存失效;
穿透是redis里不存在这个缓存key;
击穿是redis某一个热点key突然失效,最终的受害者都是数据库
希望这篇文章对大家有所帮助。请使用评论添加你的反馈意见,这有助于我提高自己的下一篇文章。如果有任何疑问,请在评论部分提出你的疑问,后续会持续更新博客,期望大家关注,共同进步,谢谢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix