概述
缓存穿透、击穿、雪崩
缓存穿透
定义 :客户端请求的数据不仅在缓存没有查到,而且数据库中也没有;导致每次的请求的数据都能打到数据库中去,进行的无效的查询,不仅穿过了redis层也穿mysql层
场景 :恶意的请求数据、根本就不存在的值uuid,(-1,woshilaji)恶意值等
方案 :
- 把恶意的数据用另一个redis存储起来,当请求在redis未命中时可以再查询下无缓存数据的key值,假如数据库中有新值增加,可能会带来判断误差,可以把恶意数据的key值设置的时间稍微短一些,根据实际的场景应用情况合理的设置缓存的失效时间
- 布隆过滤器
如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间越来越大。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为****,
布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。
主要使用了redis的bitmap的数据结构,就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。
缓存击穿
定义 :缓存击穿是指缓存中没有但数据库中有的数据(一般是值一个热点key缓存时间到期),这时由于并发用户特别多,同时读缓存没有数据,接着去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
场景 :当一个key失效时,同时有大量并发请求到数据库,造成还没来得及缓存数据,都去数据库中查询数据了
方案 :
-
高并发的key时设置一个永不过期的key
-
使用redis的互斥锁,注意增加锁的默认失效时防止释放锁失败导致不能重置key值
public function getKey()
{
$user = Redis::Get('name');
if (empty($user)) {//值过期
$setNx = Redis::Setnx('name_setnx_key', 1, 5);//设置5秒的有效期,若释放锁失,其他进程还可使用
if ($setNx == 1) {//拿到锁
$name = 'leisen';
Redis::Set('name', $name);
Redis::Del('name_setnx_key');//释放锁
} else//未拿到锁,等待两秒,重新获取key值
sleep(2);
$this->getKey();
}
}
dd($user);
}
- 接口限流 与熔断 ,降级 。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。
缓存雪崩
定义 :缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大,和缓存击穿不同的是, 缓存击穿是同一个key,缓存雪崩不同key同时过期,很多数据都查不到从而查数据库。
场景 :网页首页的基本数据信息,同一时间设置缓存,几乎同一时间失效。
方案:
-
可以把缓存数据的有效期进行随机化,防止出现同一时间大量数据过期现象发生。
-
把一些数据可以设置永久不过期,当有改动时主动删除并且设置缓存数据
最后
以上就是爱撒娇凉面为你收集整理的Redis中缓存穿透、击穿、雪崩基本解决方案缓存穿透、击穿、雪崩的全部内容,希望文章能够帮你解决Redis中缓存穿透、击穿、雪崩基本解决方案缓存穿透、击穿、雪崩所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复