美文网首页
如何正确的使用缓存,什么是缓存穿透

如何正确的使用缓存,什么是缓存穿透

作者: singleZhang2010 | 来源:发表于2020-10-19 10:56 被阅读0次

    什么是缓存穿透

    看如下这个代码案例:

    <?php
    function getList($key)
    {
      $list = $redis->get($key);//查询缓存
      if (!empty($list )) return $list ;
      $list = $this->getDb();//没有查询到缓存,从数据库中获取
      $redis->set($key,$list ,$time);//设置缓存
      return $list ;
    }
    

    上述案例中没有缓存穿透解决方案,在高并发下,如果缓存过期,会有多个请求到数据库,导致数据库崩溃。

    如何解决?

    <?php
    function getList($key){
      $list = $redis->get($key);//查询缓存
      if (!empty($list))  return $list;
      $list= $this->getDb();//没有查询到缓存,从数据库中获取//如果缓存穿透后,数据库中没查询到数据,自定义数据,写入缓存
      if (empty($list)) $list = [];
      $redis->set($key,$list);
      return $list;
    }
    

    在缓存失效情况下,如果只想要一个请求到数据库中,该怎么处理

    <?php
    function getList($key){
      $data = $redis->get($key);//查询缓存
      if (!empty($data)) {
        //缓存未过期,返回数据
        if ($data['expireTime']>time()) return $data['data'];
        //缓存已过期,获取锁,如果未获取到锁,则返回过期数据
        if (!$redis->setNx()) return $data['data'];
      }
      $list = $this->getDb();//从数据库中获取
    
      if (empty($list)) $list = [];
      $expireTime = 120;//缓存时间为 120秒//设置过期时间
      $data = [
        'data'=>$list,
        'expireTime'=>$expireTime - 60
      ];
      $redis->set($key,$data,$expireTime);
      return $list;
    }
    

    上述方案可以解决缓存穿透,避免雪崩效应,加上锁机制,到达数据库的请求只有一个。
    关于过期时间,使用我们自己的过期时间操作缓存数据有更大的灵活空间。缓存时间比我们业务定义的过期时间晚 60秒。这样,我们有60秒的时间刷新最新的数据到缓存数据库中。

    相关文章

      网友评论

          本文标题:如何正确的使用缓存,什么是缓存穿透

          本文链接:https://www.haomeiwen.com/subject/kvlkmktx.html