【问题标题】:Laravel - Erase all cache / redis keys that contain a specific stringLaravel - 擦除包含特定字符串的所有缓存/redis键
【发布时间】:2016-05-06 14:12:20
【问题描述】:

是否可以使用 Laravel 擦除 redis 中与特定字符串匹配的所有键?例如,如果我想忘记包含单词 products 的键,它会忘记以下键:

laravel:896235872385237588327582370375acaca235325:products-list laravel:896235872385237588327582370375acaca235325:产品类别

我会在 redis 服务器上运行它,但我想知道是否有更好的东西可以直接通过 Laravel 运行:

redis-cli keys "*" | grep "products" | xargs redis-cli DEL

【问题讨论】:

    标签: laravel caching redis


    【解决方案1】:

    为什么不:

    public function forget($key_name)
    {
        $redis = Cache::getRedis();
        $keys = $redis->keys("*$key_name*");
        $count = 0;
        foreach ($keys as $key) {
            $redis->del($key);
            $count++;
        }      
        return $count;  
    }
    

    对于生产环境,SCAN cursor [MATCH pattern] [COUNT count] 应该被用来代替“keys”

    http://redis.io/commands/scan

    因为您不想在 redis 中有数万个键的情况下耗尽内存,并且您不想通过使用“键”来阻塞整个 redis 实例。

    【讨论】:

    • 我看不出这在概念上有何不同?
    • 你的解决方案:从redis获取所有key到PHP(可能是几十万)然后过滤,我的解决方案:在redis端做过滤。
    【解决方案2】:

    这是使用扫描代替键的替代方法。如果需要,请随意将其转换为递归函数。

    public function forgetWildcard(string $pattern, int $maxCountValue = 1000)
    {
            $redis = Cache::getRedis();
            $currentCursor = '0';
            do {
                $response = $redis->scan($currentCursor, 'MATCH', $pattern, 'COUNT', $maxCountValue);
                $currentCursor = $response[0];
                $keys = $response[1];
                if (count($keys) > 0) {
                    // remove all found keys
                    $redis->del($keys);
                }
            } while ($currentCursor !== '0'); // finish if current Cursor is reaching '0'
    }
    

    提示:要使其适用于带有前缀的 Laravel,我必须将模式替换为以下内容: $this->getPrefix().'*:'.$pattern

    【讨论】:

      【解决方案3】:

      所以我想出了一个办法——这不是你想经常做的事情,因为它使用了 redis keys 命令:

      public function forget($key_name)
          {
              $redis = Cache::getRedis();
              $keys = $redis->keys("*");
              $count = 0;
              foreach ($keys as $key) {
                  if (strpos($key, $key_name)) {
                      $redis->del($key);
                      $count++;
                  }
              }      
              return $count;  
          }
      

      【讨论】:

      • 没有。不要这样做。使用SCAN 而不是键。
      猜你喜欢
      • 1970-01-01
      • 2020-07-27
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      相关资源
      最近更新 更多