一、KEYS:全量遍歷鍵
KEYS pattern
功能:用來獲取此數據庫中所有的鍵名
注意事項:
KEYS命令需要遍歷Redis中的所有鍵,當鍵的數量較多時會影響性能,不建議在生產環境下使用
支持glob風格通配符格式,見下表:
符號 含義 ? 匹配一個字符 * 匹配任意個(包括0個)字符 [] 匹配括號間的任一字符, 可以使用“-”符號表示一個范圍,如a [b-d]可以匹配“ab"、ac"和“ad" \x 匹配字符x,用于轉義符號。如要匹配“?"就需要使用\? KEYS命令使用擴展
因為Redis采取單線程架構,如果Redis包含了大量的鍵,那么執行該命令可能會造成Redis阻塞,所以一般建議不要在生產環境下使用該命令
有時候確實有遍歷鍵的需求,那么可以在下面三種情況下使用:
在一個不對外提供服務的Redis從節點上執行,這樣不會阻塞到客戶端 的請求,但是會影響到主從復制
如果確認鍵值總數確實比較少,可以執行該命令
使用下面要介紹的scan命令漸進式的遍歷所有鍵,可以有效防止阻 塞。
演示案例
下面是一些基本使用:
當需要遍歷所有鍵時(例如檢測過期或閑置時間、尋找大對象等),KEYS是一個很有幫助的命令。例如想刪除所有以video字符串開頭的鍵,可以執行下面的命令:
redis-cli keys video* | xargs redis-cli del
二、SCAN:漸進式遍歷鍵
命令介紹
Redis從2.8版本后,提供了一個新的命令scan,它能有效的解決keys命令存在的問題
和keys命令執行時會遍歷所有鍵不同,scan采用漸進式遍歷的方式來解決keys命令可能帶來的阻塞問題,每次scan命令的時間復雜度是O(1),但是要真正實現keys的功能,需要執行多次scan
Redis存儲鍵值對實際使用的是hashtable的數據結構.
那么每次執行scan,可以想象成只掃描一個字典中的一部分鍵,直到將字典中的所有鍵遍歷完畢
SCAN命令可能會產生的問題
如果在SCAN過程中有鍵發生變化(增加、刪除、修改),那么遍歷可能會遇到如下問題:新增的鍵可能沒有遍歷到,遍歷出了重復的鍵等情況,也就是說SCAN并不能保證完整的遍歷出來所有的鍵,這在開發時需要考慮
?命令格式
scan cursor [match pattern] [count number]
參數:
cursor是必需參數,實際上cursor是一個游標,第一次遍歷從0開始,每次scan遍歷完都會返回當前游標的值,直到游標值為0,表示遍歷結束
match pattern是可選參數,它的作用的是做模式的匹配,這點和keys的模式匹配很像
count number是可選參數,它的作用是表明每次要遍歷的鍵個數,默認值是10,此參數可以適當增大
演示案例
例如當前Redis數據庫中有26個鍵(26個英文字母),現在我們要分3次遍歷完數據庫中的26個鍵
第一次執行"scan 0",返回兩部分:
第一部分10,代表下次scan需要的cursor
第二部分是返回的11個鍵
第二次執行“scan 10”,因為上一次返回10,所以從“cursor=10”開始掃描,結果如下所示,返回10個鍵
第二次執行“scan 3”,因為上一次返回3,所以從“cursor=3”開始掃描,結果如下所示,返回5個鍵
上圖中SCAN命令返回0,代表所有的鍵已經遍歷完,所以遍歷結束
擴展
除了scan之外,Redis提供了面向哈希類型、集合類型、有序集合的掃描遍歷命令。例如hgetall、smembers、zrange可能產生的阻塞問題,對應的命令分別是hscan、sscan、zscan,它們的用法和scan基本類似
例如,下面以sscan為例,當前集合有兩種類型的元素,分別為old:user和new:user開頭,現需要將old:user開頭的元素全部刪除,可以參考下面的偽代碼:
String key = "myset";
//定義pattern
String pattern = "old:user*";
// 游標每次從0開始
String cursor = "0";
while (true) {//獲取掃描結果ScanResult scanResult = redis.sscan (key, cursor, pattern) ;List elemelts 上scanResult.getResult() ;if (elements != nu1l && elements.size () > 0) {//批量刪除.redis.srem(key, elements) ;}//獲取新的游標cursor = scanResult. getSStringCursor();/ /如果游標為0表示遍歷結果if ("0".equals(cursor)){break;}
}
三、EXISTS:判斷鍵是否存在
EXISTS key [key2 key3...]
功能:判斷鍵是否存在
返回值:
成功返回存在的鍵數
失敗返回整數0
演示案例
四、RENAME:鍵的重命名
RENAME key newkey
功能:用來重命名一個鍵
返回值:
更改的鍵存在,成功返回更改后的名稱
更改的鍵不存在,返回錯誤
演示案例
?例如當前數據庫中有一個鍵名為Hello,現在將其重命名為World
五、DEL:刪除鍵
DEL key [key2 key3...]
功能:刪除鍵
返回值:
返回刪除的成功的鍵數
如果刪除一個不存在的鍵,返回0
注意事項:
DEL不支持通配符,但是我們可以結合Linux的管道和xargs命令自己實現刪除所有符合規則的鍵。例如要刪除以“user:”開頭的鍵,可以執行redis-cli KEYS "user:*" | xargs redis-cli DEL
另外,由于DEL命令支持多個鍵參數,所以執行redis-cli DEL 'redis-cli KEYS "user:*" '達到同樣的效果,但是性能更好
演示案例
六、RANDOMKEY:隨機返回一個鍵
RANDOMKEY
功能:每次執行隨機返回數據庫中的一個鍵?
返回值:
如果有鍵,隨機返回一個鍵
如果沒有鍵,返回null
演示案例
例如當前數據庫中26個鍵,每次執行命令會隨機返回一個鍵
七、TYPE:獲取鍵類型
TYPE key
功能:用來獲得鍵的數據類型,而不是鍵值的數據類型
返回值:
string:字符串類型
hash:散列類型
list:列表類型
set:集合類型
zet:有序集合類型
演示案例
八、DBSIZE:獲取鍵總數
dbsize
功能:用來返回當前數據庫中鍵的總數
返回值:返回當前數據庫中鍵的總數
與KEYS命令的區別
dbsize命令在計算鍵總數時不會遍歷所有鍵,而是直接獲取Redis內置的鍵總數變量,所以dbsize命令的時間復雜度為O(1)
而keys命令會遍歷所有鍵,所以它的時間復雜度是O(n),當Redis保存了大量鍵時,線上環境禁止使用
演示案例
例如當前數據庫中有26個鍵