您好,登錄后才能下訂單哦!
這篇文章主要介紹“Redis怎么刪除數量過萬以上Key而不影響業務”,在日常操作中,相信很多人在Redis怎么刪除數量過萬以上Key而不影響業務問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Redis怎么刪除數量過萬以上Key而不影響業務”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
有時候因為 Redis Key 沒有設置過期時間或者因為業務需求或者Redis內存不足或者修改Redis Key值等需求,并且這些Key是有規律的,可以通過正則表達式來匹配。
一般通過網上搜索,會告訴你使用下面方法,Redis 提供了一個簡單暴力的指令 keys用來列出所有滿足特定正則字符串規則的 key。
$ redis-cli --raw keys "testkey-*" | xargs redis-cli del
通過 Redis keys 來匹配你需要刪除的key,再使用 xargs 把結果傳給 redis-cli del ,這樣看似完美,實則有很大風險。
上面命令使用非常簡單,提供一個簡單的正則字符串即可,但是有很明顯的兩個缺點。
沒有 offset、limit 參數,一次性吐出所有滿足條件的 key,萬一實例中有幾百 w 個 key 滿足條件,當你看到滿屏的字符串刷的沒有盡頭時,你就知道難受了。
keys 算法是遍歷算法,復雜度是 O(n),如果實例中有千萬級以上的 key,這個指令就會導致 Redis 服務卡頓,所有讀寫 Redis 的其它的指令都會被延后甚至會超時報錯,因為 Redis 6 版本以下都是單線程程序,順序執行所有指令,其它指令必須等到當前的 keys 指令執行完了才可以繼續,這樣就會導致業務不可用,甚至造成redis宕機的風險。
注意:這種方法不推薦,建議生產環境屏蔽keys命令。那大家會問,有沒有更好的方法來解決這個問題?答案是當然用,請接著看下文。
Redis從2.8版本開始支持 scan 命令,SCAN命令的基本用法如下:
SCAN cursor [MATCH pattern] [COUNT count]
cursor:游標,SCAN命令是一個基于游標的迭代器,SCAN命令每次被調用之后,都會向用戶返回一個新的游標,用戶在下次迭代時需要使用這個新游標作為SCAN命令的游標參數,以此來延續之前的迭代過程,直到服務器向用戶返回值為0的游標時,一次完整的遍歷過程就結束了。
MATCH:匹配規則,例如遍歷以 testkey- 開頭的所有key可以寫成 testkey-*。
COUNT:COUNT選項的作用就是讓用戶告知迭代命令,在每次迭代中應該從數據集里返回多少元素,COUNT只是對增量式迭代命令的一種提示,并不代表真正返回的數量,例如你COUNT設置為2有可能會返回3個元素,但返回的元素數據會與COUNT設置的正相關,COUNT的默認值是10。
例子:
$ scan 0 MATCH testkey-* 1) "34" 2) 1) "testkey-2" 2) "testkey-49" 3) "testkey-20" 4) "testkey-19" 5) "testkey-93" 6) "testkey-8" 7) "testkey-34" 8) "testkey-76" 9) "testkey-13" 10) "testkey-18" 11) "testkey-10" $ scan 34 MATCH testkey-* COUNT 1000 1) "0" 2) 1) "ops-coffee-16" 2) "ops-coffee-19" 3) "ops-coffee-23" 4) "ops-coffee-21" 5) "ops-coffee-40" 6) "ops-coffee-22" 7) "ops-coffee-1" 8) "ops-coffee-11" 9) "ops-coffee-28" 10) "ops-coffee-3" 11) "ops-coffee-26" 12) "ops-coffee-4" 13) "ops-coffee-31" ...
scan 命令返回的是一個包含兩個元素的數組,第一個數組元素是用于進行下一次迭代的新游標,而第二個數組元素則是一個數組,這個數組中包含了所有被迭代的元素。
上面這個例子的意思是掃描所有前綴為testkey-的key。第一次迭代使用0作為游標,表示開始一次新的迭代,同時使用了MATCH匹配前綴為testkey-的key,返回了游標值34以及遍歷到的數據。第二次迭代使用的是第一次迭代時返回的游標,也即是命令回復第一個元素的值34,同時通過將COUNT選項的參數設置為1000,強制命令為本次迭代掃描更多元素。在第二次調用SCAN命令時,命令返回了游標0,這表示迭代已經結束,整個數據集已經被完整遍歷過了。
Redis scan 命令就是基于游標的迭代器,意味著命令每次被調用都需要使用上一次這個調用返回的游標作為該次調用的游標參數,以此來延續之前的迭代過程。當SCAN命令的游標參數被設置為0時,服務器將開始一次新的迭代,而當redis服務器向用戶返回值為0的游標時,表示迭代已結束,這是唯一迭代結束的判定方式,而不能通過返回結果集是否為空判斷迭代結束。
上面的需求,最終可以使用下面命令來解決:
$ redis-cli --scan --pattern "testkey-*" | xargs -L 1000 redis-cli del
xargs -L 指令表示xargs一次讀取的行數,也就是每次刪除key的數量,不要一次行讀取太多數量key。
scan 相比 keys 具備有以下特點:
復雜度雖然也是 O(n),但是它是通過游標分步進行的,不會阻塞線程。
提供 limit 參數,可以控制每次返回結果的最大條數,limit 只是對增量式迭代命令的一種提示(hint),返回的結果可多可少。
同 keys 一樣,它也提供模式匹配功能。
服務器不需要為游標保存狀態,游標的唯一狀態就是 scan 返回給客戶端的游標整數。
返回的結果可能會有重復,需要客戶端去重復,這點非常重要。
遍歷的過程中如果有數據修改,改動后的數據能不能遍歷到是不確定的。
單次返回的結果是空的并不意味著遍歷結束,而要看返回的游標值是否為零。
Redis 類似 scan 命令還有很多,比如:
scan 指令是一系列指令,除了可以遍歷所有的 key 之外,還可以對指定的容器集合進行遍歷
zscan 遍歷 zset 集合元素
hscan 遍歷 hash 字典的元素
sscan 遍歷 set 集合的元素
注意:SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一個參數總是一個數據庫鍵。而 SCAN 命令則不需要在第一個參數提供任何數據庫鍵,因為它迭代的是當前數據庫中的所有數據庫鍵。
到此,關于“Redis怎么刪除數量過萬以上Key而不影響業務”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。