Redis命令參考手冊——KEY(鍵)

Redis命令參考手冊——KEY(鍵)

1、DEL

格式:DEL key [key …]
刪除給定的一個或多個key。 不存在的key會被忽略。
可用版本

>=1.0.0

時間複雜度:
0(N),N爲被刪除的key的數量 刪除單個字符串類型的key,時間複雜度爲0(1)。 刪除單個列表、集合、有序集合或哈希表類型的 key ,時間複雜度爲 O(M), M 爲以上數據結構內的元素數量。
返回值:
被刪除key的數量
示例代碼:

# 刪除單個 key
redis> SET name huangz
OK
redis> DEL name
(integer) 1
# 刪除一個不存在的 key
redis> EXISTS phone
(integer) 0
redis> DEL phone # 失敗,沒有 key 被刪除
(integer) 0
# 同時刪除多個 key
redis> SET name "redis"
OK
redis> SET type "key-value store"
OK
redis> SET website "redis.com"
OK
redis> DEL name type website
(integer) 3

2、KEYS

格式:keys pattern
查找所有符合給定模式pattern的key。 KEYS 匹配數據庫中所有key。 KEYS h?ll0 匹配 hello,hallo和hxllo等。 KEYS hllo 匹配hllo和heeeeello等。 KEYS h[ae]llo 匹配hello和hallo,但不匹配hillo。 特殊符號用\隔開 警告:KEYS的速度非常快,但在一個大的數據庫中使用它仍然可能造成性能問題,如果你需要從一個數據集中查找特定的key,你最好還是用Redis的集合結構(set)來代替。
可用版本

>=1.0.0

時間複雜度:
0(N),N爲數據庫中key的數量
返回值:
符合給定模式的key列表。
示例代碼:

redis> MSET one 1 two 2 three 3 four 4 # 一次設置 4 個 key
OK
redis> KEYS *o*
1) "four"
2) "two"
3) "one"
redis> KEYS t??
1) "two"
redis> KEYS t[w]*
1) "two"
redis> KEYS * # 匹配數據庫內所有 key
1) "four"
2) "three"
3) "two"
4) "one"

3、RANDOMKEY

格式:randomkey
從當前數據庫中隨機返回(不刪除)一個key。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
當數據庫不爲空時,返回一個key。 當數據庫爲空時,返回nil。
示例代碼:

# 數據庫不爲空
redis> MSET fruit "apple" drink "beer" food "cookies" # 設置多個 key
OK
redis> RANDOMKEY
"fruit"
redis> RANDOMKEY
"food"
redis> KEYS * # 查看數據庫內所有key,證明 RANDOMKEY 並不刪除 key
1) "food"
2) "drink"
3) "fruit"
# 數據庫爲空
redis> FLUSHDB # 刪除當前數據庫所有 key
OK
redis> RANDOMKEY
(nil)

4、TTL

格式:ttl key
以秒爲單位,返回給定key的剩餘生存時間(TTL,time to live)。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
當key不存在時,返回-2. 當key存在但沒有設置剩餘生存時間,返回-1。 否則,以秒爲單位,返回key的剩餘生存時間。 注:在Redis2.8以前,當key不存在,或者key沒有設置剩餘生存時間時,命令都返回-1。
示例代碼:

# 不存在的 key
redis> FLUSHDB
OK
redis> TTL key
(integer) -2
# key 存在,但沒有設置剩餘生存時間
redis> SET key value
OK
redis> TTL key
(integer) -1
# 有剩餘生存時間的 key
redis> EXPIRE key 10086
(integer) 1
redis> TTL key
(integer) 10084

5、PTTL

格式:pttl key
這個命令類似於TTL命令,但它以毫秒爲單位返回key的剩餘生存時間,而不是像TTL命令那樣,以秒爲單位。
可用版本

>=2.6.0

時間複雜度:
0(1)
返回值:
當key不存在時,返回-2. 當key存在但沒有設置剩餘生存時間,返回-1。 否則,以秒爲單位,返回key的剩餘生存時間。 注:在Redis2.8以前,當key不存在,或者key沒有設置剩餘生存時間時,命令都返回-1。
示例代碼:

# 不存在的 key
redis> FLUSHDB
OK
redis> PTTL key
(integer) -2
# key 存在,但沒有設置剩餘生存時間
redis> SET key value
OK
redis> PTTL key
(integer) -1
# 有剩餘生存時間的 key
redis> PEXPIRE key 10086
(integer) 1
redis> PTTL key
(integer) 6179

6、EXISTS

格式:exists key
檢查給定key是否存在。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
若key存在,返回1,否則返回0。
示例代碼:

redis> SET db "redis"
OK
redis> EXISTS db
(integer) 1
redis> DEL db
(integer) 1
redis> EXISTS db
(integer) 0

7、MOVE

格式:move key db
將當前數據庫的key移動到給定的數據庫db當中。 如果當前數據庫(源數據庫)和給定數據庫(目標數據庫)有相同名字的給定key,或者key不存在與當前數據庫,那麼MOVE沒有任何效果。 因此,也可以利用這一特性,將MOVE當做鎖(locking)原語(primitive)。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
移動成功返回1,失敗則返回0。
示例代碼:

# key 存在於當前數據庫
redis> SELECT 0 #redis 默認使用數據庫 0,爲了清晰起見,這裏再顯式指定一次。
OK
redis> SET song "secret base - Zone"
OK
redis> MOVE song 1 # 將 song 移動到數據庫 1
(integer) 1
redis> EXISTS song # song 已經被移走
(integer) 0
redis> SELECT 1 # 使用數據庫 1
OK
redis:1> EXISTS song # 證實 song 被移到了數據庫 1 (注意命
令提示符變成了"redis:1",表明正在使用數據庫 1)
(integer) 1
# 當 key 不存在的時候
redis:1> EXISTS fake_key
(integer) 0
redis:1> MOVE fake_key 0 # 試圖從數據庫 1 移動一個不存在的 key 到數據庫
0,失敗
(integer) 0
redis:1> select 0 # 使用數據庫0
OK
redis> EXISTS fake_key # 證實 fake_key 不存在
(integer) 0
# 當源數據庫和目標數據庫有相同的 key 時
redis> SELECT 0 # 使用數據庫0
OK
redis> SET favorite_fruit "banana"
OK
redis> SELECT 1 # 使用數據庫1
OK
redis:1> SET favorite_fruit "apple"
OK
redis:1> SELECT 0 # 使用數據庫0,並試圖將 favorite_fruit 移動到數據庫 1
OK
redis> MOVE favorite_fruit 1 # 因爲兩個數據庫有相同的 key,MOVE 失敗
(integer) 0
redis> GET favorite_fruit # 數據庫 0 的 favorite_fruit 沒變
"banana"
redis> SELECT 1
OK
redis:1> GET favorite_fruit # 數據庫 1 的 favorite_fruit 也是
"apple"

8、RENAME

格式:rename key newkey
將key改名爲newkey。 當key和newkey相同,或者key不存在時,返回一個錯誤。 當newkey已經存在時,RENAME命令將覆蓋舊值。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
改名成功時提示ok,失敗時候返回一個錯誤。
示例代碼:

# key 存在且 newkey 不存
redis> SET message "hello world"
OK
redis> RENAME message greeting
OK
redis> EXISTS message # message 不復存在
(integer) 0
redis> EXISTS greeting # greeting 取而代之
(integer) 1
# 當 key 不存在時,返回錯誤
redis> RENAME fake_key never_exists
(error) ERR no such key
# newkey 已存在時, RENAME 會覆蓋舊 newkey
redis> SET pc "lenovo"
OK
redis> SET personal_computer "dell"
OK
redis> RENAME pc personal_computer
OK  #這裏相當於value換了一個新的地址引用
redis> GET pc
(nil)
redis:1> GET personal_computer # 原來的值 dell 被覆蓋了
"lenovo"

9、RENAMENX

格式:renamex key newkey
當且僅當newkey不存在時,將key改名爲newkey。 當key不存在時,返回一個錯誤。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
修改成功時,返回1。 如果newkey已經存在,返回0。
示例代碼:

# newkey 不存在,改名成功
redis> SET player "MPlyaer"
OK
redis> EXISTS best_player
(integer) 0
redis> RENAMENX player best_player
(integer) 1
# newkey 存在時,失敗
redis> SET animal "bear"
OK
redis> SET favorite_animal "butterfly"
OK
redis> RENAMENX animal favorite_animal
(integer) 0
redis> get animal
"bear"
redis> get favorite_animal
"butterfly"

10、TYPE

格式:type key
返回key所儲存的值的類型。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
none(key不存在) string(字符串) list(列表) set(集合) zset(有序集) hash(哈希表)
示例代碼:

# 字符串
redis> SET weather "sunny"
OK
redis> TYPE weather
string
# 列表
redis> LPUSH book_list "programming in scala"
(integer) 1
redis> TYPE book_list
list
# 集合
redis> SADD pat "dog"
(integer) 1
redis> TYPE pat
set

11、EXPIRE

格式:expire key seconds
爲給定key設置生存時間,當key過期時(生存時間爲0),它會被自動刪除。
在Redis中,帶有生存時間的key被稱爲【可揮發】(volatile)的。
生存時間可以通過使用 DEL 命令來刪除整個 key 來移除,或者被 SET 和 GETSET 命令覆(overwrite),這意味着,如果一個命令只是修改(alter)一個帶生存時間的 key 的值而不是用一個新的 key 值來代替(replace)它的話,那麼生存時間不會被改變。
比如說,對一個 key 執行 INCR 命令,對一個列表進行 LPUSH 命令,或者對一個哈希表執行 HSET 命令,這類操作都不會修改 key 本身的生存時間。
另一方面,如果使用 RENAME 對一個 key 進行改名,那麼改名後的 key 的生存時間和改名前一樣。
RENAME 命令的另一種可能是,嘗試將一個帶生存時間的 key 改名成另一個帶生存時間的 another_key ,這時舊的 another_key (以及它的生存時間)會被刪除,然後舊的 key 會改名爲 another_key ,因此,新的 another_key 的生存時間也和原本的 key 一樣。
使用 PERSIST 命令可以在不刪除 key 的情況下,移除 key 的生存時間,讓 key 重新成爲一個『持久化』(persistent) key 。
更新生存時間可以對一個已經帶有生存時間的key執行EXPIRE命令,新指定的生存時間會取代舊的生存時間。
過期時間的精確度在Redis2.4版本中,過期時間的延遲在1秒鐘之內——也即是,就算key已經過期,但它還是可能在過期之後一秒鐘之內被訪問到,而在新的Redis2.6版本中,延遲被降低到1毫秒之內。
Redis2.1.3之前的不同之處在Redis2.1.3之前的版本中,修改一個帶有生存時間的key會導致整個key被刪除,這一行爲是受當時複製(replication)層的限制而作出的,現在這一限制已經被修復。
可用版本

>=1.0.0

時間複雜度:
0(1)
返回值:
設置成功返回1。 當key不存在或者不能爲key設置生存時間時(不如在低於2.1.3版本的Redis中你嘗試更新key的生存時間),返回0。
示例代碼:

redis> SET cache_page "www.google.com"
OK
redis> EXPIRE cache_page 30 # 設置過期時間爲 30 秒
(integer) 1
redis> TTL cache_page # 查看剩餘生存時間
(integer) 23
redis> EXPIRE cache_page 30000 # 更新過期時間
(integer) 1
redis> TTL cache_page
(integer) 29996

模式:導航會話
假設你有一項 web 服務,打算根據用戶最近訪問的 N 個頁面來進行物品推薦,並且假 設用戶停止閱覽超過 60 秒,那麼就清空閱覽記錄(爲了減少物品推薦的計算量,並且保持 推薦物品的新鮮度)。 這些最近訪問的頁面記錄,我們稱之爲『導航會話』(Navigation session),可以用 INCR 和 RPUSH 命令在 Redis 中實現它:每當用戶閱覽一個網頁的時候,執行以下代碼:
MULTI
RPUSH pagewviews.user: http://…
EXPIRE pagewviews.user: 60
EXEC
如果用戶停止閱覽超過 60 秒,那麼它的導航會話就會被清空,當用戶重新開始閱覽的 時候,系統又會重新記錄導航會話,繼續進行物品推薦。

12、PEXPIRE

格式:pexpire key milliseconds
這個命令和 EXPIRE 命令的作用類似,但是它以毫秒爲單位設置 key 的生存時間,而不像 EXPIRE 命令那樣,以秒爲單位。
可用版本

>=2.6.0

時間複雜度:
0(1)
返回值:
設置成功,返回1。 key不存在或設置失敗,返回0。
示例代碼:

redis> SET mykey "Hello"
OK
redis> PEXPIRE mykey 1500
(integer) 1
redis> TTL mykey # TTL 的返回值以秒爲單位
(integer) 2
redis> PTTL mykey # PTTL 可以給出準確的毫秒數
(integer) 1499

13、EXPIREAT

格式:expireat key timestamp
EXPIREAT 的作用和 EXPIRE 類似,都用於爲 key 設置生存時間。 不同在於 EXPIREAT 命令接受的時間參數是 UNIX 時間戳(unixtimestamp)。
可用版本

>=1.2.0

時間複雜度:
0(1)
返回值:
如果生存時間設置成功,返回1。 當key不存在或沒辦法設置生存時間,返回0。
示例代碼:

redis> SET cache www.google.com
OK
redis> EXPIREAT cache 1355292000 # 這個 key 將在 2012.12.12 過期
(integer) 1
redis> TTL cache
(integer) 45081860

14、PEXPIREAT

格式:pexpireat key milliseconds
這個命令和 EXPIREAT 命令類似,但它以毫秒爲單位設置 key 的過期 unix 時間戳,而不是像 EXPIREAT 那樣,以秒爲單位。
可用版本

>=2.6.0

時間複雜度:
0(1)
返回值:
如果生存時間設置成功,返回1。 當key不存在或沒辦法設置生存時間,返回0。
示例代碼:

redis> SET mykey "Hello"
OK
redis> PEXPIREAT mykey 1555555555005
(integer) 1
redis> TTL mykey # TTL 返回秒
(integer) 223157079
redis> PTTL mykey # PTTL 返回毫秒
(integer) 223157079318

15、PERSIST

格式:persist key
移除給定 key 的生存時間,將這個 key 從『可揮發』的(帶生存時間 key )轉換成『持久化』的(一個不帶生存時間、永不過期的 key )。
可用版本

>=2.2.0

時間複雜度:
0(1)
返回值:
如果生存時間設置成功,返回1。 當key不存在或沒辦法設置生存時間,返回0。
示例代碼:

redis> SET mykey "Hello"
OK
redis> EXPIRE mykey 10 # 爲 key 設置生存時間
(integer) 1
redis> TTL mykey
(integer) 10
redis> PERSIST mykey # 移除 key 的生存時間
(integer) 1
redis> TTL mykey
(integer) -1

16、SORT

格式:sort key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination]
返回或保存給定列表、集合、有序集合 key 中經過排序的元素。 排序默認以數字作爲對象,值被解釋爲雙精度浮點數,然後進行比較。
一般用法
最簡單的SORT使用方法是SORT key。 假設today_cost是一個保存數字的列表,SORT命令默認會返回該列表的值得遞增(從小到大)排序結果。
示例代碼:

# 將數據一一加入到列表中
redis> LPUSH today_cost 30
(integer) 1
redis> LPUSH today_cost 1.5
(integer) 2
redis> LPUSH today_cost 10
(integer) 3
redis> LPUSH today_cost 8
(integer) 4
# 排序
redis> SORT today_cost
1) "1.5"
2) "8"
3) "10"
4) "30"
當數據集中保存的是字符串值時,你可以用ALPHA修飾符(modifier)進行排序。
# 將數據一一加入到列表中
redis> LPUSH website "www.reddit.com"
(integer) 1
redis> LPUSH website "www.slashdot.com"
(integer) 2
redis> LPUSH website "www.infoq.com"
(integer) 3
# 默認排序
redis> SORT website
1) "www.infoq.com"
2) "www.slashdot.com"
3) "www.reddit.com"
# 按字符排序
redis> SORT website ALPHA
1) "www.infoq.com"
2) "www.reddit.com"
3) "www.slashdot.com"

如果你正確設置了 !LC_COLLATE 環境變量的話,Redis 能識別 UTF-8 編碼。 排序之後返回的元素數量可以通過LIMIT 修飾符進行限制。 LIMIT 修飾符接受兩個參數: offset 和 count 。 offset 指定要跳過的元素數量,count 指定跳過 offset 個指定的元素之後,要返回多少個對象。
以下例子返回排序結果的前 5 個對象( offset 爲 0 表示沒有元素被跳過)。

# 將數據一一加入到列表中
redis> LPUSH rank 30
(integer) 1
redis> LPUSH rank 56
(integer) 2
redis> LPUSH rank 42
(integer) 3
redis> LPUSH rank 22
(integer) 4
redis> LPUSH rank 0
(integer) 5
redis> LPUSH rank 11
(integer) 6
redis> LPUSH rank 32
(integer) 7
redis> LPUSH rank 67
(integer) 8
redis> LPUSH rank 50
(integer) 9
redis> LPUSH rank 44
(integer) 10
redis> LPUSH rank 55
(integer) 11
# 排序
redis> SORT rank LIMIT 0 5 # 返回排名前五的元素
1) "0"
2) "11"
3) "22"
4) "30"
5) "32"

修飾符可以組合使用。以下例子返回降序(從大到小)的前 5 個對象。

redis> SORT rank LIMIT 0 5 DESC
1) "78"
2) "67"
3) "56"
4) "55"
5) "50"

使用外部key進行排序
有時候你會希望使用外部的 key 作爲權重來比較元素,代替默認的對比方法。 假設現在有用戶(user)數據如下:

id name level
1 admin 999
2 huangz 10
59230 jack 3
222 hacker 9999

id 數據保存在 key 名爲 user_id 的列表中。 name 數據保存在 key 名爲username{id} 的列表中 level 數據保存在userlevel{id} 的 key 中。
示例代碼:

# 先將要使用的數據加入到數據庫中
# admin
redis> LPUSH user_id 1
(integer) 1
redis> SET user_name_1 admin
OK
redis> SET user_level_1 9999
OK
# huangz
redis> LPUSH user_id 2
(integer) 2
redis> SET user_name_2 huangz
OK
redis> SET user_level_2 10
OK
# jack
redis> LPUSH user_id 59230
(integer) 3
redis> SET user_name_59230 jack
OK
redis> SET user_level_59230 3
OK
# hacker
redis> LPUSH user_id 222
(integer) 4
redis> SET user_name_222 hacker
OK
redis> SET user_level_222 9999
OK

如果希望按 level 從大到小排序user_id ,可以使用以下命令:

redis> SORT user_id BY user_level_* DESC
1) "222" # hacker
2) "1" # admin
3) "2" # huangz
4) "59230" # jack

但是有時候只是返回相應的 id 沒有什麼用,你可能更希望排序後返回 id 對應的用戶名,這樣更友好一點,使用 GET 選項可以做到這一點:

redis> SORT user_id BY user_level_* DESC GET user_name_*
1) "hacker"
2) "admin"
3) "huangz"
4) "jack"

可以多次地、有序地使用 GET 操作來獲取更多外部 key 。 比如你不但希望獲取用戶名,還希望連用戶的密碼也一併列出,可以使用以下命令:

# 先添加一些測試數據
redis> SET user_password_222 "hey,im in"
OK
redis> SET user_password_1 "a_long_long_password"
OK
redis> SET user_password_2 "nobodyknows"
OK
redis> SET user_password_59230 "jack201022"
OK
# 獲取name 和password
redis> SORT user_id BY user_level_* DESC GET user_name_* GET
user_password_*
1) "hacker" # 用戶名
2) "hey,im in" # 密碼
3) "jack"
4) "jack201022"
5) "huangz"
6) "nobodyknows"
7) "admin"
8) "a_long_long_password"
# 注意GET 操作是有序的,GET user_name_* GET user_password_* 和 GET user_password_* GET user_name_*返回的結果位置不同
redis> SORT user_id BY user_level_* DESC GET user_password_* GET
user_name_*
1) "hey,im in" # 密碼
2) "hacker" # 用戶名
3) "jack201022"
4) "jack"
5) "nobodyknows"
6) "huangz"
7) "a_long_long_password"
8) "admin"

GET 還有一個特殊的規則—— “GET #” ,用於獲取被排序對象(我們這裏的例子是user_id )的當前元素。 比如你希望 user_id 按 level 排序,還要列出 id 、 name 和password ,可以使用以下命令:

redis> SORT user_id BY user_level_* DESC GET # GET user_name_* GET user_password_*
1) "222" # id
2) "hacker" # name
3) "hey,im in" # password
4) "1"
5) "admin"
6) "a_long_long_password"
7) "2"
8) "huangz"
9) "nobodyknows"
10) "59230"
11) "jack"
12) "jack201022"

只獲取對象而不排序
BY 修飾符可以將一個不存在的 key 當作權重,讓 SORT 跳過排序操作。 該方法用於你希望獲取外部對象而又不希望引起排序開銷時使用。

# 確保fake_key 不存在
redis> EXISTS fake_key
(integer) 0
# 以fake_key 作BY 參數,不排序,只GET name 和 GET password
redis> SORT user_id BY fake_key GET # GET user_name_* GET
user_password_*
1) "222" # id
2) "hacker" # user_name
3) "hey,im in" # password
4) "59230"
5) "jack"
6) "jack201022"
7) "2"
8) "huangz"
9) "nobodyknows"
10) "1"
11) "admin"
12) "a_long_long_password"

保存排序結果
默認情況下, SORT 操作只是簡單地返回排序結果,如果你希望保存排序結果,可以給STORE 選項指定一個 key 作爲參數,排序結果將以列表的形式被保存到這個 key 上。(若指定 key 已存在,則覆蓋。)

redis> EXISTS user_info_sorted_by_level # 確保指定key 不存在
(integer) 0
redis> SORT user_id BY user_level_* GET # GET user_name_* GET
user_password_* STORE user_info_sorted_by_level # 排序
(integer) 12 # 顯示有12 條結果被保存了
redis> LRANGE user_info_sorted_by_level 0 11 # 查看排序結果
1) "59230"
2) "jack"
3) "jack201022"
4) "2"
5) "huangz"
6) "nobodyknows"
7) "222"
8) "hacker"
9) "hey,im in"
10) "1"
11) "admin"
12) "a_long_long_password"

一個有趣的用法是將 SORT 結果保存,用 EXPIRE 爲結果集設置生存時間,這樣結果集就成了 SORT 操作的一個緩存。 這樣就不必頻繁地調用 SORT 操作了,只有當結果集過期時,才需要再調用一次 SORT操作。 有時候爲了正確實現這一用法,你可能需要加鎖以避免多個客戶端同時進行緩存重建(也就是多個客戶端,同一時間進行 SORT 操作,並保存爲結果集),具體參見 SETNX 命令。
在GET和BY中使用哈希表
可以使用哈希表特有的語法,在 SORT 命令中進行 GET 和 BY 操作。

# 假設現在我們的用戶表新增了一個 serial 項來爲作爲每個用戶的序列號
# 序列號以哈希表的形式保存在 serial 哈希域內。
redis> HMSET serial 1 23131283 2 23810573 222 502342349 59230
2435829758
OK
# 用 serial 中值的大小爲根據,對 user_id 進行排序
redis> SORT user_id BY *->serial
1) "59230"
2) "222"
3) "2"
4) "1"

符號 “->” 用於分割哈希表的鍵名(key name)和索引域(hash field),格式爲"key->field" 。 除此之外,哈希表的 BY 和 GET 操作和上面介紹的其他數據結構(列表、集合、有序集合)沒有什麼不同。
可用版本:

>=1.0.0

時間複雜度:
O(N+M*log(M)), N 爲要排序的列表或集合內的元素數量, M 爲要返回的元素數量。 如果只是使用 SORT 命令的 GET 選項獲取數據而沒有進行排序,時間複雜度 O(N)。
返回值:
沒有使用 STORE 參數,返回列表形式的排序結果。 使用 STORE 參數,返回排序結果的元素數量。

17、OBJECT

格式:object subcommand [arguments [arguments]]
OBJECT 命令允許從內部察看給定 key 的 Redis 對象。 它通常用在除錯(debugging)或者瞭解爲了節省空間而對 key 使用特殊編碼的情況。 當將 Redis 用作緩存程序時,你也可以通過 OBJECT 命令中的信息,決定 key 的驅逐策略(eviction policies)。
OBJECT命令有多個子命令:
1.OBJECT REFCOUNT 返回給定 key 引用所儲存的值的次數。此命令主要用於除錯。 2.OBJECT ENCODING 返回給定 key 鎖儲存的值所使用的內部表示(representation)。 3.OBJECT IDLETIME 返回給定 key 自儲存以來的空轉時間(idle, 沒有被讀取也沒有被寫入),以秒爲單位。
對象可以以多種方式編碼:
1.字符串可以被編碼爲 raw (一般字符串)或 int (用字符串表示 64 位數字是爲了節約空間)。
2.列表可以被編碼爲 ziplist 或 linkedlist 。ziplist 是爲節約大小較小的列表空間而作的特殊表示。
3.集合可以被編碼爲 intset 或者 hashtable 。intset 是隻儲存數字的小集合的特殊表示。
4.哈希表可以編碼爲 zipmap 或者 hashtable。zipmap 是小哈希表的特殊表示。
5.有序集合可以被編碼爲 ziplist 或者 skiplist 格式。ziplist 用於表示小的有序集合,而 skiplist 則用於表示任何大小的有序集合。
假如你做了什麼讓 Redis 沒辦法再使用節省空間的編碼時(比如將一個只有 1 個元素的集合擴展爲一個有 100 萬個元素的集合),特殊編碼類型(specially encoded types)會自動轉換成通用類型(general type)。
可用版本:

>=2.2.3

時間複雜度:
0(1)
返回值:
REFCOUNT 和IDLETIME 返回數字。 ENCODING 返回相應的編碼類型。
示例代碼:

redis> SET game "COD" # 設置一個字符串
OK
redis> OBJECT REFCOUNT game # 只有一個引用
(integer) 1
redis> OBJECT IDLETIME game # 等待一陣。。。然後查看空轉時間
(integer) 90
redis> GET game # 提取 game, 讓它處於活躍(active)狀態
"COD"
redis> OBJECT IDLETIME game # 不再處於空轉
(integer) 0
redis> OBJECT ENCODING game # 字符串的編碼方式
"raw"
redis> SET phone 15820123123 # 大的數字也被編碼爲字符串
OK
redis> OBJECT ENCODING phone
"raw"
redis> SET age 20 # 短數字被編碼爲 int
OK
redis> OBJECT ENCODING age
"int"

18、MIGRATE

格式:migrate host port key destination-db timeout
將 key 原子性地從當前實例傳送到目標實例的指定數據庫上,一旦傳送成功, key 保證會出現在目標實例上,而當前實例上的 key 會被刪除。
這個命令是一個原子操作,它在執行的時候會阻塞進行遷移的兩個實例,直到以下任意結果發生:遷移成功,遷移失敗,等到超時。
命令的內部實現是這樣的:它在當前實例對給定 key 執行 DUMP 命令 ,將它序列化,然後傳送到目標實例,目標實例再使用 RESTORE 對數據進行反序列化,並將反序列化所得 的數據添加到數據庫中;當前實例就像目標實例的客戶端那樣,只要看到 RESTORE 命令返回 OK ,它就會調用 DEL 刪除自己數據庫上的 key 。
timeout 參數以毫秒爲格式,指定當前實例和目標實例進行溝通的最大間隔時間。這說明操作並不一定要在 timeout 毫秒內完成,只是說數據傳送的時間不能超過這個 timeout 數。
MIGRATE 命令需要在給定的時間規定內完成 IO 操作。如果在傳送數據時發生 IO 錯誤,或者達到了超時時間,那麼命令會停止執行,並返回一個特殊的錯誤: IOERR 。
當 IOERR 出現時,有以下兩種可能: 1.key 可能存在於兩個實例 2.key 可能只存在於當前實例
唯一不可能發生的情況就是丟失 key ,因此,如果一個客戶端執行 MIGRATE 命令,並且不幸遇上 IOERR 錯誤,那麼這個客戶端唯一要做的就是檢查自己數據庫上的 key 是否已 經被正確地刪除。
如果有其他錯誤發生,那麼 MIGRATE 保證 key 只會出現在當前實例中。(當然,目標實例的給定數據庫上可能有和 key 同名的鍵,不過這和 MIGRATE 命令沒有關係)。
可用版本:

>=2.6.0

時間複雜度:
這個命令在源實例上實際執行 DUMP 命令和 DEL 命令,在目標實例執行 RESTORE 命令,查看以上命令的文檔可以看到詳細的複雜度說明。 key 數據在兩個實例之間傳輸的複雜度爲 O(N) 。
返回值:
遷移成功時返回 OK ,否則返回相應的錯誤。
示例:
先啓動兩個 Redis 實例,一個使用默認的 6379 端口,一個使用 7777 端口。

$ ./redis-server &
[1] 3557
...
$ ./redis-server --port 7777 &
[2] 3560
...

然後用客戶端連上 6379 端口的實例,設置一個鍵,然後將它遷移到 7777 端口的實例上:

$ ./redis-cli
redis 127.0.0.1:6379> flushdb
OK
redis 127.0.0.1:6379> SET greeting "Hello from 6379 instance"
OK
redis 127.0.0.1:6379> MIGRATE 127.0.0.1 7777 greeting 0 1000
OK
redis 127.0.0.1:6379> EXISTS greeting # 遷移成功後 key 被刪除
(integer) 0

使用另一個客戶端,查看 7777 端口上的實例:

$ ./redis-cli -p 7777
redis 127.0.0.1:7777> GET greeting
"Hello from 6379 instance"

19、DUMP

格式:dump key
序列化給定 key ,並返回被序列化的值,使用 RESTORE 命令可以將這個值反序列化爲Redis 鍵。
序列化生成的值有以下幾個特點: 1.它帶有 64 位的校驗和,用於檢測錯誤, RESTORE 在進行反序列化之前會先檢查 校驗和。 2.值的編碼格式和 RDB 文件保持一致。 3.RDB 版本會被編碼在序列化值當中,如果因爲 Redis 的版本不同造成 RDB 格式不兼容,那麼 Redis 會拒絕對這個值進行反序列化操作。 序列化的值不包括任何生存時間信息。
可用版本:

>=2.6.0

時間複雜度:
查找給定鍵的複雜度爲 O(1) ,對鍵進行序列化的複雜度爲 O(N*M) ,其中 N 是構成key 的 Redis 對象的數量,而 M 則是這些對象的平均大小。 如果序列化的對象是比較小的字符串,那麼複雜度爲O(1)。
返回值:
如果 key 不存在,那麼返回 nil 。 否則,返回序列化之後的值。
示例代碼:

redis> SET greeting "hello, dumping world!"
OK
redis> DUMP greeting
"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
redis> DUMP not-exists-key
(nil)

20、RESTORE

格式:restore key ttl serialized-value
反序列化給定的序列化值,並將它和給定的 key 關聯。 參數 ttl 以毫秒爲單位爲 key 設置生存時間;如果 ttl 爲 0 ,那麼不設置生存時間。 RESTORE 在執行反序列化之前會先對序列化值的 RDB 版本和數據校驗和進行檢查,如果 RDB 版本不相同或者數據不完整的話,那麼 RESTORE 會拒絕進行反序列化,並返回一個錯誤。 更多信息可以參考 DUMP 命令。
可用版本:

>=2.6.0

時間複雜度:
查找給定鍵的複雜度爲 O(1) ,對鍵進行反序列化的複雜度爲 O(NM) ,其中 N 是構成 key 的 Redis 對象的數量,而 M 則是這些對象的平均大小。 有序集合(sorted set)的反序列化複雜度爲O(NM*log(N)) ,因爲有序集合每次插入的複雜度爲O(log(N)) 。 如果反序列化的對象是比較小的字符串,那麼複雜度爲 O(1)。
返回值:
如果反序列化成功那麼返回 OK ,否則返回一個錯誤。
示例代碼:

redis> SET greeting "hello, dumping world!"
OK
redis> DUMP greeting
"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
redis> RESTORE greeting-again 0 "\x00\x15hello, dumping
world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
OK
redis> GET greeting-again
"hello, dumping world!"
redis> RESTORE fake-message 0 "hello moto moto blah blah" ; 使用錯誤的值進行反序列化
(error) ERR DUMP payload version or checksum are wrong
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章