《玩轉Redis》系列文章主要講述Redis的基礎及中高級應用,文章基於Redis5.0.4 。本文主要講述Redis的Key相關命令,主要包含以下內容:
- 【Key過期命令】:EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT、TTL、PTTL;
- 【其他Key命令】:DEL、EXISTS、KEYS、DUMP、MIGRATE、MOVE、PERSIST、RANDOMKEY、RENAME、RENAMENX、RESTORE、TOUCH、TYPE、UNLINK、WAIT、OBJECT、SORT;
最新思維導圖原圖可於公衆號【zxiaofan】留言獲取。
1、Key過期命令
1.1、Key過期命令簡述
- 設置過期時間爲一段時間後(EXPIRE、PEXPIRE);
- 設置過期時間爲指定時間點(EXPIREAT、PEXPIREAT);
- 查詢過期時間(TTL、PTTL);
命令 | 功能 | 參數 |
---|---|---|
EXPIRE | 設置key的過期時間 | key seconds |
PEXPIRE | 設置key的過期時間(毫秒) | key milliseconds |
EXPIREAT | 設置key的過期時間爲Unix時間戳(since 1970-01-01) | key timestamp |
PEXPIREAT | 設置key的過期時間爲Unix毫秒時間戳(since 1970-01-01) | key milliseconds-timestamp |
TTL | 查詢指定key的剩餘生存時間 | key |
PTTL | 查詢指定key的剩餘生存時間(毫秒) | key |
1.2、Key過期命令注意
- Redis Version >= 2.6.0後,過期時間支持毫秒;
- 過期時間支持設置一段時間後過期,也支持設置指定時間點過期;
- 過期時間和電腦時鐘相關,如果修改時鐘爲未來的時間,則key會立即過期;
- key被rename後,新key過期時間沿用舊key的過期時間;
- version<=2.4時,過期精度有0-1S誤差,Redis2.6起(支持PSETEX),誤差縮小到0-1MS;
- 以上6個命令時間複雜度都是O(1);
- 【TTL、PTTL】
- Redis version <= 2.6:key不存在或存在且未設置過期時間返回-1;
- Redis version >=Redis 2.8:key不存在返回-2;存在且未設置過期時間返回-1;
1.3、Key過期命令詳細對比分析
1.4、Key過期命令示例
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> expire dyh 5
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 0
127.0.0.1:6378> expire dyh 5
(integer) 0
127.0.0.1:6378> ttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> expire dyh 50
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 47
127.0.0.1:6378> ttl dyh
(integer) 44
127.0.0.1:6378> pexpire dyh 3000
(integer) 1
127.0.0.1:6378> pttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> pexpire dyh 30000
(integer) 1
127.0.0.1:6378> pttl dyh
(integer) 26575
127.0.0.1:6378> pttl dyh
(integer) 25039
127.0.0.1:6378> pexpireat dyh 1572536378000
(integer) 0
127.0.0.1:6378> pttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> pexpireat dyh 1572536378000
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 86359
127.0.0.1:6378> ttl dyh
(integer) 86357
2、Redis其他Key命令
2.1、Redis其他Key命令簡述
Redis的Key命令衆多,支持各式各樣的功能:刪除、查找、迭代、判斷、排序、移動等。
命令 |
功能 | 參數 |
---|---|---|
DEL | 刪除指定key | key [key …] |
EXISTS | 判斷指定key是否存在 | key [key …] |
KEYS | 查找指定Pattern的key | pattern |
DUMP | 返回指定key序列化後的值 | key |
MIGRATE | 原子遷移指定key到指定實例的指定DB | host port key | “” destination-db timeout [COPY] [REPLACE] [KEYS key [key …]] |
MOVE | 移動key到指定DB | key db |
PERSIST | 移除key的超時時間 | key |
RANDOMKEY | 返回一個隨機key | 無參 |
RENAME | 重命名key | key newkey |
RENAMENX | newkey不存在時重命名key | key newkey |
RESTORE | 反序列化數據並存儲到指定key | key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency] |
SORT | 返回list、set、sorted list排序後的數據 | key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC |
TOUCH | (批量)修改key的最後訪問時間 | key [key …] |
TYPE | 查詢key類型 | key |
UNLINK | 將keys從keyspace中刪除,後續將異步刪除value | key [key …] |
WAIT | 阻塞客戶端直到超時或之前的寫命令被同步到指定數量的副本 | numreplicas timeout(毫秒) |
OBJECT | 調試key對應的value,常用於優化 | subcommand [arguments [arguments …]] |
2.2、Redis其他Key命令注意
-
【EXISTS】判斷指定key是否存在
- key存在返回1,不存在返回0;
- 參數key有多個時,返回存在key的數量;
- 3.0.3支持多參數;
-
【KEYS】查找指定Pattern的key
- 命令功能強大,但性能低下,建議使用SCAN替代;
- 掃描1百萬key需要40ms,大數據庫下性能非常低下;
- 僅用於調試或特殊操作,如鍵空間keyspace改變;
- pattern通配符:
- ?:任一字符; *:任意多個字符
- [ae]:匹配a或e; [^e]:匹配非e
- [a-b]:匹配a-b之間(含)的字符
- \ : 字符轉義
-
【DUMP】返回指定key序列化後的值
- 序列化的值不包含過期時間;
- 序列化結果包含64位校驗和用於檢查錯誤;
- 編碼格式和RDB使用的格式一致;
- 序列化值包含RDB版本信息,RDB格式不兼容的Redis版本,將拒絕處理序列化的值(拒絕反序列化操作);
-
【MIGRATE】原子遷移指定key到指定實例的指定DB
- 原理:源DB執行DUMP DEL;目標DB執行RESTORE。源DB DUMP》目標DB RESTORE》目標DB返回“OK”則源DB DEL;
- 遷移時會阻塞2個實例,直到成功或者超時(毫秒)、異常;
- 遷移多key:key參數爲“”,keys指定多key;
- 超時(毫秒)不是指完成時間,而是指數據傳輸時間;
- IOERR:
- MIGRATE需要在指定時間完成IO操作,如果IO異常或超時將返回IOERR;
- 可能產生2種場景:1、key存在於2個實例;2、key僅存在於源實例;
- key丟失不肯能發生;
- 如果遇到超時,應檢查key是否存在於目標實例;
- 如果返回異常(ERR開頭),MIGRATE保證key僅存在於源實例(除非目標實例有同名key);
- AUTH不能放在KEYS參數後;
-
【MOVE】移動key倒指定DB
- 當前DB不存在該key ==》 不移動;
- 目標DB已有該key ==》 不移動;
-
【RENAME】重命名key
- key不存在:error(no such key);
- <Redis3.2.0,若新舊key名字相同,會返回異常"ERR source and destination objects are the same";
- 原理:先刪除key再添加新key;
- 如果原key是big key,會導致高延遲;
- 注意和【RENAMENX】對比學習;
-
【RESTORE】反序列化數據並存儲到指定key
- 序列化值可通過DUMP獲得;
- ttl爲0表示不設置超時時間,否則設置超時時間(單位毫秒);
- Redis》=5…0:支持ABSTTL修飾符,ttl表示Unix時間戳(毫秒);
- IDLETIME seconds:設置反序列化的值的idletime,idletime可通過Object idletime key 查詢;
- FREQ frequency:設置反序列化的值的FREQ,FREQ 可通過Object freq key 查詢;
- key已存在:返回(error) BUSYKEY Target key name already exists.【或者使用REPLACE修飾符】;
- RESTORE將檢查RDB版本信息以及數據校驗和,不匹配將返回異常;
- RESTORE時間複雜度:O(1) O(N*M)
- O(1):創建新key;
- N:組成value的數據結構的元素數量;
- M:組成value的數據結構的元素的平均大小;
- value是小字符串:O(1) O(1*M)且M較小,故近似看成O(1);
- value是sorted set:複雜度是O(NMlog(N)),因爲插入數據到sorted sets是O(log(N));
-
【SORT】返回list、set、sorted list排序後的數據
- 默認按照數值由小到大排序,按照雙精度浮點數進行比較;
- 逆序:DESC;
- 字母順序排序:ALPHA,不使用此修飾符會異常;
- 正確設置!LC_COLLATE環境變量後,可使用lIMIT修飾符;
- 外部key排序:SORT user_id BY user_level_* DESC GET user_name_*;
- *實際是user_id(列表)中value的佔位符;
- by對應key不存在時,將不會排序;
- GET返回排序結果對應的值;
- #將返回列表元素本身;
- STORE resultkey:保存排序結果到指定key;
-
【TYPE】查詢key類型
- 返回類型:string, list, set, zset, hash and stream;
-
【UNLINK】將keys從keyspace中刪除,後續將異步刪除value
- 和DEL類似。刪除key:DEL、UNLINK都是同步;刪除value:DEL是同步,UNLINK是異步;
- 常用於刪除大key(4.0.0之前可使用Pipeline批量刪除value);
-
【WAIT】阻塞客戶端直到超時或之前的寫命令被同步到指定數量的副本
- WAIT命令返回時,當前連接所有之前的寫命令一定會被指定數量的副本接收;
- 如果WAIT命令是多事物的一部分,WAIT將不會阻塞而是儘快返回參數指定的副本數量;
- timeout爲0意味着一直阻塞;
- 不論成功失敗,WAIT都將返回處理的副本數量,客戶端應檢查返回結果是否大於等於預期;
- 【一致性】
- WAIT不保證強一致性;
- 在哨兵Sentinel或Redis Cluster的故障轉移中,可以提高數據安全性;
- 【實現細節】
- 基於PSYNC(Redis主從同步)特性,副本會帶上已處理過的偏移量,可應用於多種場景:
- 1、檢測副本超時情況;2、連接斷開後再同步;3、實現WAIT;
- WAIT場景中:當客戶端執行寫命令後,Redis會記錄副本的偏移量。執行WAIT時,Redis會檢測副本是否已經完成該操作或者已經執行更新的操作;
-
【OBJECT】調試key對應的value,常用於優化
- refcount或idletime子命令:返回數字;
- 返回指定key對應value被引用的次數;
- 場景:整數共享對象池節省內存;
- encoding子命令:返回value的底層結構;
- 返回key對應的value的底層結構;
- IDLETIME
- 返回key被閒置(未寫未讀)的時間(秒);
- 當Redis內存策略是LRU或noeviction時可用;
- FREQ
- 返回key的對數訪問頻率計數器;
- 結合SCAN獲取熱key;
- key不存在:返回nil;
- OBJECT可以瞭解value的類型;
- 根據調試信息設置key的回收策略;
- refcount或idletime子命令:返回數字;
2.3、Redis其他Key命令詳細對比分析
-
DEL、UNLINK、EXISTS、KEYS、DUMP詳細對比分析:
-
MIGRATE、MOVE、PERSIST、RENAME、RENAMENX詳細對比分析:
-
RESTORE、RANDOMKEY、TOUCH、TYPE、WAIT詳細對比分析:
-
OBJECT、SORT詳細對比分析:
2.4、Redis其他Key命令示例
2.4.1、unlink、del、exists、keys示例
127.0.0.1:6378> set key1 dyh
OK
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> unlink key1
(integer) 1
127.0.0.1:6378> del key2
(integer) 1
127.0.0.1:6378> exists key1 key2
(integer) 0
127.0.0.1:6378> keys key*
1) "key3"
2) "keylist"
3) "key4"
4) "key"
127.0.0.1:6378> keys key?
1) "key3"
2) "key4"
127.0.0.1:6378> keys key[35]
1) "key3"
127.0.0.1:6378> keys key[^3]
1) "key4"
2.4.2、dump示例
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> get key2
"@zxiaofan"
127.0.0.1:6378> dump key2
"\x00\t@zxiaofan\t\x00\xe8\xd2c%\x02\xc7]="
2.4.3、move示例
127.0.0.1:6378> set key1 hi
OK
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> select 1
OK
127.0.0.1:6378[1]> del key1
(integer) 0
127.0.0.1:6378[1]> set key2 @zxiaofan-db1
OK
127.0.0.1:6378[1]> select 0
OK
127.0.0.1:6378> move key1 1
(integer) 1
127.0.0.1:6378> move key2 1
(integer) 0
127.0.0.1:6378> get key1
(nil)
127.0.0.1:6378> get key2
"@zxiaofan"
127.0.0.1:6378> select 1
OK
127.0.0.1:6378[1]> get key2
"@zxiaofan-db1"
2.4.4、rename、renamenx示例
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> rename key2 key2019
OK
127.0.0.1:6378> rename key2 key2019
(error) ERR no such key
127.0.0.1:6378> set key1 hi
OK
127.0.0.1:6378> rename key2019 key1
OK
127.0.0.1:6378> get key1
"@zxiaofan"
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> renamenx key2019 key1
(error) ERR no such key
127.0.0.1:6378> renamenx key2 key1
(integer) 0
127.0.0.1:6378> rename key2 key1
OK
2.4.5、type示例
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> type key2
string
127.0.0.1:6378> set key1 1
OK
127.0.0.1:6378> type key1
string
127.0.0.1:6378> lpush listkey csdn github zxiaofan.com
(integer) 6
127.0.0.1:6378> type listkey
list
127.0.0.1:6378> hmset hashkey name zxiaofan blog csdn
OK
127.0.0.1:6378> type hashkey
hash
2.4.5、RANDOMKEY示例
127.0.0.1:6378> RANDOMKEY
"list3"
127.0.0.1:6378> RANDOMKEY
"num4"
127.0.0.1:6378> RANDOMKEY
"dyh"
127.0.0.1:6378> mget list3 num4 dyh
1) (nil)
2) "200"
3) "@zxiaofan"
127.0.0.1:6378>
3、總結
關於Redis的Key命令,你掌握了多少了呢?不清楚的趕緊往上翻翻。
- 過期時間支持哪幾種;
- 如何查詢指定key的過期時間;
- 如何移除指定key的過期時間;
- 如何判斷Redis中是否存在某些key,若存在返回值是什麼;
- 功能強大的KEYS命令通配符支持哪些;
- key可以重命名嗎,重命名需要注意什麼;
- SORT排序支持哪幾種數據類型,各數據類型默認排序規則是怎樣的;
- UNLINK和DEL的區別是什麼;
- OBJECT命令都有哪些子命令,如何應用於調試分析;
Redis的Key相關命令到此結束了嗎?路漫漫其修遠兮…
- SCAN系列命令(SCAN / SSCAN / HSCAN /ZSCAN),如何高性能處理海量Redis數據;
- SORT實戰中如何排序;
- Object實戰中如何用於性能分析。
敬請關注後續《玩轉Redis》系列文章。
祝君好運!
Life is all about choices!
將來的你一定會感激現在拼命的自己!
【CSDN】【GitHub】【OSCHINA】【掘金】【微信公衆號】