redis缓存穿透之setnx使用场景

本文探讨了业务增长和高并发下引入Redis缓存的重要性,着重讲解了缓存穿透问题及其影响,如数据库连接超时。提出了利用Redis的setnx命令实现进程锁,确保在缓存失效时只有一个进程读取数据库并更新缓存,从而避免大量请求对数据库造成冲击。通过这种方式,以空间换时间,提高系统效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    随着业务的增长,请求并发的增大。很多公司在业务场景中会增加缓存策略,而缓存用的最多的也就是redis了。

    今天我们来说一下缓存穿透,我们缓存一般是有时效性的,一定的生命周期过去之后就会消失,一般的系统不会设置永久性的存储,这时候就会遇到一个问题,要么就是主动刷新缓存,要么就是程序被动刷新缓存。

    事实证明很多程序当中很少主动刷新因为你要去写脚本,定时去刷新数据,这样的话代价比较大。所以较多的就选择了程序被动刷新缓存,就是在缓存失效之后读库在写入缓存。这里就会导致一个问题那就是:当缓存失效的那一刻大量的请求过来就会直接打到数据库上,如果并发量大的话读库操作肯定会有影响,连接超时,连接数过大这样的情况也会随时遇到。

    针对这种情况redis有一个进程锁也就是我们今天说的setnx

    下面直接贴代码:

    $ret = $this->redis->get('k' . $abbr);
    if (empty($ret)) {
    $ret1 = $this->redis->setnx('k'.$abbr,$ret);
        if($ret1){
        $sql = "select * from xxx where a=xx;";
        $query = $this->db->query($sql);
        $ret = $query->result_array();
        $this->redis->set('b' , json_encode($ret) , 6400);
        $this->redis->set('bakk', json_encode($ret) , 10000);
        }    else{
            $ret = $this->redis->get('bakk' . $abbr);
        }

    }

    这段程序的逻辑就是先用一个进程去请求数据如果没有了用setnx锁住这个键只有一个进程去读库操作然后重写两个键值,一个主要的查询键值,一个备份的键值当然缓存时间会长点。这样不管多少请求过来只有一个进程去做读库操作,其他的还是读redis备份数据。用空间来换取时间和效率还是比较划算的。

    这就是针对缓存穿透做的一套操作,下面上一下这个流程图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值