Redis 之 缓存预热 & 缓存雪崩 & 缓存击穿 & 缓存穿透

目录

一、缓存预热

[1.1 缓存预热是什么?](#1.1 缓存预热是什么?)

[1.2 解决方案:](#1.2 解决方案:)

二、缓存雪崩

[2.1 缓存雪崩是什么?怎么发生的?](#2.1 缓存雪崩是什么?怎么发生的?)

[2.2 怎么解决](#2.2 怎么解决)

三、缓存穿透

[3.1 是什么?怎么产生的呢?](#3.1 是什么?怎么产生的呢?)

[3.2 解决方案](#3.2 解决方案)

3.2.1、采用回写增强,

3.2.2、加上一个布隆过滤器,

四、缓存击穿

[4.1 是什么?](#4.1 是什么?)

[4.2 怎么解决](#4.2 怎么解决)

五、总结


一、缓存预热

1.1 缓存预热是什么?

缓存预热是指在系统启动或者高峰期之前,提前将数据加载到缓存中 ,避免在用户请求的时候,先查询数据库(这样第一个查询的人就会比较慢),再把查询结果回写到redis当中去。

1.2 解决方案:

为了防止用户访问的时候Redis中没有数据,所以提前将热点数据保存到Redis里面(通过LRU数据删除策略,可以得到高频数据队列),通过脚本的方式将热点数据提前加入。

二、缓存雪崩

2.1 缓存雪崩是什么?怎么发生的?

缓存雪崩是指在缓存系统中,大量缓存数据同时失效或过期 ,导致请求直接打到数据库或后端服务,从而引起数据库压力过大或服务崩溃的现象。

  • redis 主机挂了, Redis全盘崩溃,偏硬件运维
  • redis 中有大量key 同时过期大面积失效,偏软件开发

2.2 怎么解决

1、针对于redis服务器问题,可以采用redis的高并发策略:使用主从复制 + 哨兵 ,或者直接使用redis集群模式,并且这时候需要开启redis的持久化机制,方便从机上位的时候能够快速恢复之前的数据。

2、多缓存预防雪崩:不仅仅只用redis这么一个缓存,也可以在本地加上一个ehcache缓存,把哪些高频信息给存储进来,这样就不需要所有的数据都需要去redis上面去找了。

3、服务降级: 直接就不让用户前来访问容易出现问题的信息了,直接提示当前访问人数过多,请稍后再试。

4、人民币玩家:直接使用阿里云的云数据库redis版

三、缓存穿透

3.1 是什么?怎么产生的呢?

缓存穿透 就是请求去查询一条数据,先查redis,redis里面没有,再查mysql,mysql里面无,都查询不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增

缓存穿透可能是由于恶意攻击缓存设置不当或者数据更新频繁等原因引起的。

缓存穿透最怕的情况就是黑客恶意攻击,比如他现在知道了你key的格式:abc xxx,正好这个数据你的redis没有,MySQL当中也没有,那么他就会一直查这个,导致你的redisMySQL接受一次次的暴击。怎么解决这个问题呢?

3.2 解决方案

3.2.1、采用回写增强,

既然都是黑客了,逃过布隆过滤器还不是简简单单?

如果发生了缓存穿透,我们可以针对要查询的数据,在Redis里存一个和业务部门商量后确定的缺省值(比如,零、负数、defaultNull等)。

比如,键uid:abcdxxx,值defaultNull作为案例的key和value

先去redis查键uid:abcdxxx没有,再去mysql查没有获得 ,这就发生了一次穿透现象。

but,可以增强回写机制

mysql也查不到的话也让redis存入刚刚查不到的key并保护mysql****。这样等下次再来查这个值的时候,就不会发生缓存穿透了。

但是,此方法架不住黑客的恶意攻击**,有缺陷......,只能解决key相同的情况**,假如黑客可以找到不同的key,总不能每个key都回写到redis里吧?这时候我们就需要新的解决方法了。

3.2.2、加上一个布隆过滤器

布隆过滤器可以过滤掉大部分不存在的情况(当然也有一定的漏判率)。我们在数据访问redis之前可以先让他去通过一下布隆过滤器,如果布隆中没有,那么就是肯定没有,直接返回就行了。

四、缓存击穿

4.1 是什么?

缓存击穿就是大量请求同时查询一个key(或一批)时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去,也就是热点key突然都失效了,MySQL承受高并发量

简单说就是:热点key突然失效,导致MySQL被暴打

4.2 怎么解决

  1. 设置热点数据的永不过期策略:对于一些非常热门的数据,可以将其缓存时间设置为永不过期,这样可以避免缓存失效导致的击穿问题。但需要注意,这种方式可能会导致缓存数据不及时更新的问题。

  2. 互斥更新,采用双检加锁机制

    多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。

    其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。

五、总结

相关推荐
程序人生51811 分钟前
PostgreSQL分区表
数据库·postgresql·分区表
bug菌¹34 分钟前
滚雪球学MySQL[3.1讲]: 高级SQL查询
数据库·sql·mysql
燕雀安知鸿鹄之志哉.37 分钟前
玄机:第二章 日志分析-mysql应急响应
数据库·经验分享·mysql·安全·web安全·网络安全
Janusne1 小时前
高效修复MySQL数据库
数据库·mysql·phpmyadmin·dbf for mysql
才艺のblog2 小时前
PG数据库的Jsonb全文检索查询
数据库·postgresql·jsonb
PieroPc2 小时前
用 Django 5 快速生成一个简单 进销存 系统 添加 个打印 按钮
数据库·python·django
mtc8n242 小时前
MySQL知识点复习 - 存储过程
数据库·mysql
Y_3_72 小时前
Redis列表 (List) 类型详解:从命令使用到实际应用
linux·数据库·redis·ubuntu·缓存·bootstrap·list
程序那点事儿2 小时前
MongoDB 数据库服务搭建(单机)
linux·运维·数据库·mongodb