【转】缓存雪崩的解决方案

缓存雪崩:

当缓存服务器重启或者是在某一时间段大量缓存集体失效的时候,高并发请求集体请求后端数据库系统,就会对数据库系统带来很大压力。

解决方案:

1.加锁排队:

加锁排队可以减轻数据库压力,但无法提高系统吞吐量,真正的高并发情况下,假设缓存重建期间key一直是锁着的,后面的请求都在阻塞,会造成大量用户超时等待。

2.随机值缓存。

简单来说就是我们将缓存失效时间分散开,在原有失效时间的基础上增加随机值,这样缓存过期时间的重复率就会大大降低,很难引发集体缓存失效的事件。

class getPrizeList {
    /**
     * redis实例
     * @var \Redis
     */
    private $redis;
 
    /**
     * @var string
     */
    private $redis_key = '|prize_list';
 
    /**
     * 缓存标记key
     * @var string
     */
    private $cash_key = '|prize_list_cash';
 
    /**
     * 过期时间
     * @var int
     */
    private $expire = 30;
 
    /**
     * getPrizeList constructor.
     * @param $redis
     */
    public function __construct($redis)
{
        $this->redis = $redis;
    }
 
    /**
     * @return array|bool|string
     */
    public function fetch()
{
        $cash_result = $this->redis->get($this->cash_key);
        $result = $this->redis->get($this->redis_key);
        if(!$cash_result) {
            $this->redis->set($this->cash_key, 1, $this->expire);
            //此处应该进行数据库查询...
            //$result = 数据库查询结果, 并且设置的时间要比cash_key长,这里设置为2倍;
            $this->redis->set($this->redis_key, $result, $this->expire * 2);
        }
 
        return $result;
    }
}

缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;

缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值