踩坑记录 PHP实现 Redis使用SCAN 和 SSCAN(不要用scan!!!!!)

1 篇文章 0 订阅
文章讲述了在项目中由于使用keys命令导致Redis卡死的问题,以及尝试使用scan命令作为替代却引发CPU飙升的情况。指出尽管scan比keys更不易阻塞,但在大量key的情况下仍可能导致性能问题。最终解决方案是记录缓存key并直接获取,同时建议在线上环境中禁用keys和scan。文中提供了PHP实现的Redis scan和sscan函数示例。
摘要由CSDN通过智能技术生成

补充一下,前一段时间因为项目中使用keys导致redis卡死,于是在网上搜索解决方法,基本都是使用scan替代keys命令。然后就上线了scan替代keys。。。然后就踩坑了

结果就是redis的cpu飙升,scan操作同样是扫描表操作,会导致cpu飙高,也同样会阻塞请求

scan和keys的区别在于:keys是全表扫描,会导致阻塞,scan类似分页扫描表,通过游标接着往下扫,所以扫的数据比keys少,

相对于keys比较不容易阻塞,但不代表它不会导致阻塞,如果key数量很多,快速连续调用 SCAN,那么对 CPU 的压力会增大,会造成cpu飙升,有性能问题。

所以keys和scan在生产环境都应该禁用,最后的解决方法还是记录缓存的key,然后直接获取key。

测试环境之所以redis使用keys和scan命令没有性能问题,是因为测试环境的的key数量很少,就算整体扫描也不会有问题,所以就是:

1、缓存key时设定过期时间,这样redis就不会有大量的未失效的key

2、线上禁止使用keys和scan

下面的就不用看了 总之keys不能用,scan也不能用!!!!!!

PHP实现 Redis使用SCAN 和 SSCAN

因为大家都知道的原因(线上禁止使用keys smembers 命令

所以用了scan 和 sscan命令获取redis中的值

取出来的数据记得去重


//使用scan匹配all key
    function scanAllForMatch($pattern, $cursor=null, $results=[]) {

        if ($cursor === "0") {
            return $results;
        }

        if ($cursor === null) {
            $cursor = "0";
        }

        $redis = Cache::getRedis();
        list($cursor, $result) = $redis->scan($cursor, 'match', $pattern, 'count', 1000);

        $results = array_merge($results, $result);

        return scanAllForMatch($pattern, $cursor, $results);

    }

//使用sscan匹配 set 集合中 all key
    function setScanAllForMatch($key, $pattern='*', $cursor=null, $count = 3000, $results=[]) {

        if ($cursor === "0") {
            return $results;
        }

        if ($cursor === null) {
            $cursor = "0";
        }

        $redis = Cache::getRedis();
        list($cursor, $result) = $redis->sscan($key, $cursor, 'match', $pattern, 'count', $count);

        $results = array_merge($results, $result);


        return setScanAllForMatch($key, $pattern, $cursor, $count, $results);

    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值