redis如何實現(xiàn)批量刪除key功能

keys

在測試環(huán)境使用redis的時候,經(jīng)常會要批量刪除key菲驴,我們但是redis并沒有提供批量刪除的命令悬荣,但是我們可以在命令行下,使用keys遍歷鍵實現(xiàn)

//批量刪除以video開頭的key
redis-cli keys video* | xargs redis-cli del

//以j秉宿,r開頭戒突,緊跟edis字符串的所有鍵
redis-cli keys [j,r]edis | xargs redis-cli del
注意:
    redis是單線程架構(gòu),如果redis包含了大量的鍵描睦,執(zhí)行keys命令可能會造成redis阻塞膊存,所以一般建議不要在生產(chǎn)環(huán)境下使用keys命令。
    如果非要遍歷鍵刪除的話,可以在一下三種情況使用:
    (1)在一個不對外提供服務(wù)的Redis從節(jié)點上執(zhí)行隔崎,這樣不會阻塞到客戶端的請求今艺,但是會影響到主從復(fù)制。
    (2)如果確認鍵值總數(shù)確實比較少爵卒,可以執(zhí)行該命令虚缎。
    (3)使用scan命令漸進式的遍歷所有鍵,可以有效防止阻塞钓株。

漸進式遍歷

scan命令文檔

Redis提供了面向哈希類型实牡、集合類型、有序集合的掃描遍歷命令轴合,解決諸如hgetall创坞、smembers、zrange可能產(chǎn)生的阻塞問題受葛,對應(yīng)的命令分別是hscan题涨、sscan、zscan奔坟,它們的用法和scan基本類似携栋。

注意:
漸進式遍歷可以有效的解決keys命令可能產(chǎn)生的阻塞問題搭盾,但是scan并非完美無瑕咳秉,如果在scan的過程中如果有鍵的變化(增加、刪除鸯隅、修改)澜建,
那么遍歷效果可能會碰到如下問題:新增的鍵可能沒有遍歷到,遍歷出了重復(fù)的鍵等情況蝌以,也就是說scan并不能保證完整的遍歷出來所有的鍵炕舵,這些是我們在開發(fā)時需要考慮的。

<?php

namespace Redis;


use Redis;

class RedisTest
{
    const PORT = 6379;

    /**
     * redis對象
     */
    public $redis = null;

    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', self::PORT);
    }

    public function info()
    {
        print_r($this->redis->info());
    }

    /**
     * 刪除前綴是test:的key
     */
    public function keyDelete()
    {
        $pre = 'test:';

        for ($i = 0; $i < 10; $i++) {
            $this->redis->set($pre . "$i", "$i");
        }

        // Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, 'del'], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }
    }
}

返回結(jié)果

array (
  0 => 'test:8',
)
array (
  0 => 'test:1',
)
array (
  0 => 'test:9',
)
array (
  0 => 'test:6',
)
array (
  0 => 'test:5',
)
array (
  0 => 'test:0',
)
array (
  0 => 'test:3',
)
array (
  0 => 'test:7',
)
array (
  0 => 'test:4',
)
array (
  0 => 'test:2',
)

SSCAN跟畅、HSCAN咽筋、ZSCAN、SCAN命令的坑

// Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, 'del'], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }

根據(jù)scan的文檔說明可知:scan命令每次迭代的時候徊件,有可能返回空奸攻,但這并不是結(jié)束的標志,而是當返回的迭代的值為”0″時才算結(jié)束虱痕。

因此睹耐,上面的代碼在迭代的時候,若沒有arr_keys返回部翘,$arr_keys是個空數(shù)組硝训,所以while循環(huán)自然就中斷了,所以沒有任何輸出。

為了避免arr_keys返回是個空數(shù)組的問題我們可以這樣解決:

解決方法一
 $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

告訴redis擴展窖梁,當執(zhí)行scan命令后赘风,返回的結(jié)果集為空的話,函數(shù)不返回纵刘,而是直接繼續(xù)執(zhí)行scan命令贝次。這樣當scan函數(shù)返回的時候,要么返回false彰导,即迭代結(jié)束蛔翅。

注意:SSCAN、HSCAN位谋、ZSCAN也是一樣的邏輯

解決方法二

        //方式一
        // Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, 'del'], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }
        

        //方式二
        while (true) {
            $arr_keys = $this->redis->scan($it, "$pre*");
            if ($arr_keys === false) {//迭代結(jié)束山析,未找到匹配pattern的key
                return;
            }

            call_user_func_array([$this->redis, 'del'], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掏父,隨后出現(xiàn)的幾起案子笋轨,更是在濱河造成了極大的恐慌,老刑警劉巖赊淑,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爵政,死亡現(xiàn)場離奇詭異,居然都是意外死亡陶缺,警方通過查閱死者的電腦和手機钾挟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饱岸,“玉大人掺出,你說我怎么就攤上這事∩环眩” “怎么了汤锨?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長百框。 經(jīng)常有香客問我闲礼,道長,這世上最難降的妖魔是什么铐维? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任柬泽,我火速辦了婚禮,結(jié)果婚禮上方椎,老公的妹妹穿的比我還像新娘聂抢。我一直安慰自己,他們只是感情好棠众,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布琳疏。 她就那樣靜靜地躺著有决,像睡著了一般。 火紅的嫁衣襯著肌膚如雪空盼。 梳的紋絲不亂的頭發(fā)上书幕,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音揽趾,去河邊找鬼台汇。 笑死,一個胖子當著我的面吹牛篱瞎,可吹牛的內(nèi)容都是我干的苟呐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼俐筋,長吁一口氣:“原來是場噩夢啊……” “哼牵素!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起澄者,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笆呆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粱挡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赠幕,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年询筏,在試婚紗的時候發(fā)現(xiàn)自己被綠了榕堰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡屈留,死狀恐怖局冰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灌危,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布碳胳,位于F島的核電站勇蝙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挨约。R本人自食惡果不足惜味混,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诫惭。 院中可真熱鬧翁锡,春花似錦、人聲如沸夕土。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至角溃,卻和暖如春拷获,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背减细。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工匆瓜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人未蝌。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓驮吱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親萧吠。 傳聞我的和親對象是個殘疾皇子糠馆,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容