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

什么是缓存穿透

看如下这个代码案例:

<?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秒的时间刷新最新的数据到缓存数据库中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值