簡體   English   中英

如何使用phpredis在PHP中刪除多個具有相同模式的redis鍵?

[英]How to delete multiple redis keys with the same pattern in PHP using phpredis?

通過使用phpredis ,我在分頁中保存了一些數據,如下所示:

   review/itemA/1
   review/itemA/2 

其中12是頁碼。 我在文檔中讀到您可以使用通配符來檢索多個鍵。

$allKeys = $redis->keys('*');   // all keys will match this.
$keyWithUserPrefix = $redis->keys('user*');

但是,當有人發布新評論時,我是否也可以使用通配符刪除所有舊鍵? 我可以做類似的事情:

$redis->delete('review/itemA/*'); // or  $redis->delete('review/itemA*')

然而它沒有用。

否 - Redis 的DEL lete 不接受通配符,您必須明確命名鍵。 請參閱此處了解可能的方向: https : //stackoverflow.com/a/23399125/3160475

使用phpredis ,您可以獲得前綴(phpredis 會自動在任何地方添加前綴)並以這種方式刪除鍵模式:

<?php
...

$prefix = $redisClient->getOption(Redis::OPT_PREFIX);
$redisClient->delete(array_map(
    function ($key) use ($prefix) {
        return str_replace($prefix, '', $key);
    }, $redisClient->keys('*'))
);
$bash = 'redis-cli --scan --pattern "' . $path . '*" | xargs -L 1000 redis-cli DEL';

$res = @shell_exec($bash);

我只是用

$redis->delete($redis->keys('*'));

這對我來說很好用。

Predis ( ->del ) 也允許傳遞鍵數組。
它在這里工作並且比foreachdel更快。

$prefix = $this->client->getOptions($this->OPT_PREFIX);
$keys = $this->client->keys("$key*");
if ($keys) $this->client->del($keys);

使用Predis ,我這樣做:

    public function delete($key) {
        $keys = $this->client->keys($key);
        foreach ($keys as $key) {
            $this->client->del($key);
        }
    }

刪除功能沒有通配符 解決方法如下,

// returns total number of keys deleted
function delete($key) {
    if (empty($key)) {  // empty key can delete all
      return false;
    }
    $keys = $redis->keys("$key*");  // keys() function returns array of key strings. `*` wild card pattern can be changed as per need
    if(!$keys) {
        return 0;
    }
    $prefix = $redis->getOption(\Redis::OPT_PREFIX); // keys already have prefix, so we clear until delete finish.
    $redis->setOption(\Redis::OPT_PREFIX, '');
    $count = $redis->del($keys);  // del() function delete array of keys and returns number of keys deleted.
    $redis->setOption(\Redis::OPT_PREFIX, $prefix);

    return $count;
}

注意:正如@Akash Gangrade 所評論的,由於性能原因,不建議使用 keys()。 您可以考慮基於標簽的緩存失效,如https://symfony.com/doc/current/components/cache/cache_invalidation.html#tag-aware-adapters

# The keys set in redis
/*
1) "review/itemA/5"
2) "review/itemA/2"
3) "review/itemA/3"
4) "review/itemA/1"
5) "review/itemA/4"
*/

/**
 * Vars for scan
 */
$i = null;
$result = [];

/**
 * Scan redis using desired pattern
 */
while ($result != 0) {
    $result = $redis->scan($i, 'review/itemA/*');
    if (!empty($result)) {
        $all_keys[] = $result;
    }
}

# Use call_user_func_array to flatten multidimensional array into indexed array
## Scan may return duplicate keys, so use array_unique
$unlink_keys = array_unique(call_user_func_array('array_merge', $all_keys));

# As of Redis 4.0 use unlink instead of del to stop blocking
$redis->unlink($unlink_keys);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM