2022年01月07日整理发布:一起学习Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法

2023-08-04 17:16:52 来源:互联网

推荐(免费):redis

缓存穿透:键中对应的缓存数据不存在,导致请求数据库造成数据库的双重压力。

缓存崩溃:redis过期后的瞬间,大量用户请求相同的缓存数据,导致所有这些请求都请求数据库,给数据库带来了双倍的压力。为了一把钥匙,


(相关资料图)

缓存雪崩:缓存服务器宕机或大量缓存集在一定时间内失效,导致所有请求都去数据库,数据库压力翻倍的情况。这是多把钥匙。

一、缓存穿透的解决方案

常用的方法可以使用布隆过滤器拦截数据。其次,还有一个解决方案,就是如果请求的数据为空,缓存空值,不会有穿透?服务器端编程语言(Professional Hypertext Preprocessor的缩写)

类getPrizeList {

/**

* redis实例

* @var \Redis

*/

私有$ redis

/**

* @var字符串

*/

private $ redis _ key=" | prize _ list ";

/**

*到期时间

* @var int

*/

private $ expire=30

/**

* getPrizeList构造函数。

* @param $redis

*/

公共函数__construct($redis)

{

$ this-redis=$ redis;

}

/**

* @返回数组| bool |字符串

*/

公共函数提取

{

$ result=$ this-redis-get($ this-redis _ key);

if(!isset($ result)){ 0

//应该在这里进行数据库查询。

//如果查询结果不存在,缓存其默认的空数组。

$ result=[];

$ this-redis-set($ this-redis _ key,$result,$ this-expire);

}

返回$ result

}

}二、缓存崩溃的解决方案

使用互斥键,即当一个键过期时,多个请求来允许一个请求操作数据库,其他请求等待第一个请求成功返回结果后再请求。服务器端编程语言(Professional Hypertext Preprocessor的缩写)

类getPrizeList {

/**

* redis实例

* @var \Redis

*/

私有$ redis

/**

* @var字符串

*/

private $ redis _ key=" | prize _ list ";

/**

* @var字符串

*/

private $ setnx _ key=" | prize _ list _ setnx ";

/**

*到期时间

* @var int

*/

private $ expire=30

/**

* getPrizeList构造函数。

* @param $redis

*/

公共函数__construct($redis)

{

$ this-redis=$ redis;

}

/**

* @返回数组| bool |字符串

*/

公共函数提取

{

$ result=$ this-redis-get($ this-redis _ key);

if(!isset($ result)){ 0

if($ this-redis-setnx($ this-setnx _ key,1,$ this-expire)){ 0

//应该在这里进行数据库查询。

//$result=数据库查询结果;

$ this-redis-set($ this-redis _ key,$result,$ this-expire);

$ this-redis-del($ this-setnx _ key);//删除互斥体

} else {

//其他请求每10毫秒重新请求一次。

睡眠(10);

self:fetch

}

}

返回$ result

}

}三、缓存雪崩的解决方案

这种情况是由于多个密钥同时过期造成的数据库压力。一种方法可以在密钥到期时间的基础上增加随机次数,以扩展到期时间,降低缓存时间到期的重复率。另一种方法是锁定和排队,有点像上面的缓存崩溃的解决方案。然而,请求的数量太大,例如5,000个请求到来,4,999个请求等待。这势必是一个永久性的问题,不仅用户体验差,在分布式环境下更是雪上加霜。因此,复杂性很少用于高并发场景。最好的解决方案是使用缓存标签来确定标签是否过期,然后请求数据库,缓存数据的过期时间应该设置得比缓存标签的过期时间长。所以当一个请求操作数据库时,其他请求会获取最后一个缓存的数据?服务器端编程语言(Professional Hypertext Preprocessor的缩写)

类getPrizeList {

/**

* redis实例

* @var \Redis

*/

私有$ redis

/**

* @var字符串

*/

private $ redis _ key=" | prize _ list ";

/**

*缓存标签密钥

* @var字符串

*/

private $ cash _ key=" | prize _ list _ cash ";

/**

*到期时间

* @var int

*/

private $ expire=30

/**

* getPrizeList构造函数。

* @param $redis

*/

公共函数__construct($redis)

{

$ this-redis=$ redis;

}

/**

* @返回数组| bool |字符串

*/

公共函数提取

{

$ cash _ result=$ this-redis-get($ this-cash _ key);

$ result=$ this-redis-get($ this-redis _ key);

if(!$ cash _ result){ 0

$this-redis-set($this-cash_key,1,$ this-expire);

//应该在这里进行数据库查询。

//$result=数据库查询结果,设置时间比cash_key长,这里设置为2倍;

$ this-redis-set($ this-redis _ key,$result,$ this-expire * 2);

}

返回$ result

}

}以上就是一起学习Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决方案的详细内容!

来源:php中文网站

关键词:

推荐内容