本章將按照單個鍵,遍歷鍵,數據庫管理三個維度對一些通用命令進行介紹.java
針對單個鍵的命令,前面幾節已經介紹過一部分了,例如type
,del
,object
,exists
,expire
等,下面介紹幾個重要命令.node
rename key newkey
例如一個鍵名爲node
值爲jedis
:python
127.0.0.1:6379> get node "jedis"
下面操做將鍵node
改成java
:redis
127.0.0.1:6379> rename node java OK 127.0.0.1:6379> get java "jedis"
若是在rename
以前,鍵java
已經存在,那麼它的值也將被覆蓋.
爲了防止被強行rename
,redis
提供了renamenx
命令,確保只有newkey
不存在時候才被修改.
在使用重命名時,有兩點須要注意:shell
因爲重命名鍵期間會執行del命令刪除舊的鍵,若是鍵對應的值比較大,會存在阻塞redis
的可能性,這點不要忽視.數據庫
若是rename
和renamenx
中的key
和newkey
若是是相同的,在redis 3.2
和以前版本返回結果會不一樣.網絡
在redis 3.2
會返回OK:數據結構
127.0.0.1:6379> rename key key OK
在redis 3.2
以前會提示錯誤:運維
127.0.0.1:6379> rename key key (error) ERR source and destination objects are the same
randomkey
例如,當數據庫中有1000個鍵值對,randomkey
命令會隨機從中挑選一個.dom
127.0.0.1:6379> dbsize 1000 127.0.0.1:6379> randomkey hello 127.0.0.1:6379> randomkey java
除了expire
,ttl
命令之外,redis
還提供了expireat
,pexpire
,pttl
,persist
等一系列命令,下面分別進行說明:
expire key seconds
:鍵在seconds
秒後過時刪除.
pexpireat key timestamp
:健在秒級時間戳timestamp
後過時刪除.
127.0.0.1:6379> set hello world OK 127.0.0.1:6379> expire hello 10 (integer) 1 127.0.0.1:6379> ttl hello (integer) 7 # 還剩7秒
ttl
命令和pttl
均可以查詢鍵的剩餘時間,可是pttl
的時間精度更高能夠達到毫秒級.有三種返回值:
大於等於0
的整數:鍵剩餘的時間(ttl
單位是秒,pttl
單位是毫秒.)
-1
:鍵沒有設置過時時間.
-2
:鍵不存在.
expirereat
命令能夠設置鍵的秒級時間戳,例如若是須要將鍵hello
在2017-05-02 00:00:00
過時.
初次以外,redis 2.6
版本後提供了毫秒級的過時方案.
pexpire key milliseconds
:鍵在milliseconds
毫秒後過時.
pexpireat key milliseconds
:健在毫秒級時間戳timestamp
後過時刪除.
但不管是使用過時時間仍是時間戳,秒級仍是毫秒級,在redis
內部最終使用的都是pexpireat
.
在使用redis
相關過時命令時,須要注意如下幾點.
1) 若是expire key
的鍵不存在,返回結果爲:0
.
127.0.0.1:6379> expire not_exists_key 10 (integer) 0
2) 若是過時時間是負值,鍵將會被當即刪除,與del
命令同樣.
127.0.0.1:6379> set hello world OK 127.0.0.1:6379> expire hello -1 (integer) 1 127.0.0.1:6379> get hello (nil)
3) persist
命令能夠將鍵的過時時間清除.
127.0.0.1:6379> setex hello 30 world OK 127.0.0.1:6379> ttl hello (integer) 29 127.0.0.1:6379> persist hello (integer) 1 127.0.0.1:6379> ttl hello (integer) -1
4) 對於字符串類型鍵,執行set
命令會去掉過時時間,這個問題很容易在開發中被忽視.
127.0.0.1:6379> setex hello 30 world OK 127.0.0.1:6379> ttl hello (integer) 29 127.0.0.1:6379> set hello redis OK 127.0.0.1:6379> ttl hello (integer) -1
5) redis
不支持二級數據結構(例如:hash
,list
)內部元素的過時功能,例如不能對列表類型的一個元素作過時時間設置.
6) setex
命令做爲set+expire
的組合,不可是原子執行,同時減小了一次網絡通信時間.
遷移鍵功能很是重要,由於有時候咱們只想把部分數據由一個redis
遷移到另外一個redis
(例如從生產環境遷移到測試環境),redis
發展歷程中提供了move
,dump+restore
和migrate
三組遷移鍵的方法.
move key db
如上圖所示,move
命令因爲在redis
內部進行數據遷移,redis
內部能夠有多個數據庫,move key db
就是把指定的鍵從源數據庫移動到目標數據庫中,但不建議在生產環境使用.
dump key restore key ttl value
dump+restore
能夠實現不一樣的redis
實例之間進行數據遷移的功能,整個遷移的過程分爲兩步:
在源redis下使用dump
命令將鍵值序列化,格式採用的是RDB
格式.
在目標redis
上,restore
命令將上面序列化的的值進行復原,其中ttl
參數表明過時時間,若是ttl=0
表明沒有過時時間.
有關dump+restore
有兩點須要注意:第一:整個遷移過程並不是原子性,而是經過客戶端分步完成的.第二:遷移過程是開啓了兩個客戶端鏈接,因此dump
的結果不是在源redis
和目標redis
之間進行傳輸的.
migrate host port key|"" target-db timeout [copy] [replace] [keys key [key...]]
migrate
命令也是用於在redis
實例間進行數據遷移,實際上migrate
命令就是將dump
,restore
,del
三個命令進行組合,從而簡化了操做流程.migrate
命令具備原子性,從而從redis 3.0.6
版本之後已經支持遷移多個鍵的功能,有效地提升了遷移效率,migrate
在集羣中起到了重要的做用.
參數說明:
host
:目標redis
實例的ip.
port
:目標redis
實例的端口.
key|""
:在redis 3.0.6
版本以前migrate
只支持遷移一個鍵,因此在此處填寫要遷移的鍵.但redis 3.0.6
以後支持多個鍵的遷移,若是當前須要遷移多個鍵,此處填寫爲空字符串:""
.
target-db
:目標redis
的數據庫索引,例如要遷移到0號數據庫,這裏就寫0
.
timeout
:遷移的超時時間.
[copy]
:若是添加此選項,遷移後並不刪除鍵.
[replace]
:若是添加此選項,migrate
無論目標redis
是否存在該鍵都會將鍵正常的遷移進行覆蓋.
[keys key [key...]]
:遷移多個鍵,例如要遷移key1
,key2
,key3
就填寫keys key1 key2 key3
.
move
,dump+restore
,migrate
比較命令 | 做用域 | 原子性 | 支持多個鍵 |
---|---|---|---|
move |
redis 實例內部 |
是 | 否 |
dump+store |
redis 實例之間 |
否 | 否 |
migrate |
redis 實例之間 |
是 | 是 |
redis
提供了兩個命令遍歷全部的鍵,分別是keys
和scan
.
keys pattern
例:
查詢全部鍵:
127.0.0.1:6379> keys * 1) "node" 2) "hello" 3) "java" 4) "python"
使用表達式:
127.0.0.1:6379> keys *e* 1) "node" 2) "hello" 127.0.0.1:6379> keys [n,h]* 1) "node" 2) "hello"
通配符:
*
表明匹配任意字符.
?
表明匹配一個字符.
[]
表明匹配部分字符串,例如:[1,2]
表明匹配1,2
,[1-10]
表明匹配1
到10
的任意數字.
\x
用來轉義,例如要匹配星號,問號須要進行轉義.
若是redis
包含了大量的鍵,執行keys
命令極可能會形成redis
阻塞,全部通常建議不要在生產環境下使用keys
命令,但有時候確實有遍歷鍵的需求怎麼辦,能夠在一下三種狀況下使用:
在一個不對外提供服務的redis
從節點上執行,這樣不會阻塞到客戶端的請求.
當redis
實例下的鍵總數比較少,可執行此命令.
使用scan
命令漸進式的遍歷全部鍵,能夠有效防止阻塞.
redis
從2.8
版本後,提供一個新命令scan
,它能有效的解決keys
命令存在的問題.和keys
命令執行時會遍歷全部鍵不一樣,scan
採用漸進式遍歷的方式來解決keys
命令可能帶來的阻塞問題,每次scan
命令的時間複雜度是O(1),可是要真正實現keys
的功能,須要屢次使用scan
命令,redis
存儲鍵值對實際使用的是hashtable
的數據結構.
scan cursor [match pattern] [count number]
cursor
是必須參數,實際上cursor
是一個遊標,第一次遍歷從0
開始,每次scan
遍歷玩都會返回當前遊標的值,直到遊標值爲0
,表示遍歷結束.
match pattern
是可選參數,它的做用是作模式匹配,這點和keys
的模式匹配相同.
count number
是可選參數,它的做用是每次遍歷的鍵個數,默認值爲10
.
127.0.0.1:6379> scan 0 1) "0" # 遊標值 2) 1) "node" 2) "hello" 3) "java" 4) "python"
redis
提供了幾個面向redis
數據的操做,他分別是dbsize
,select
,flushdb
,flushall
命令.
select dbIndex
許多關係型數據庫,例如MySQL
支持在一個實例下有多個數據庫存在,可是與關係型數據庫用字符來區分不一樣數據庫名不一樣,redis
只是用數字做爲多個數據庫的實現.redis
默認配置中是有16個數據庫:
databases 16
redis 3.0
中已經開始逐漸弱化這個功能,例如redis
的分佈式實現redis cluster
只容許使用0
號數據庫,只不過爲了向下兼容老版本的數據庫功能,該功能沒有徹底廢棄掉.
廢棄多數據庫的緣由:
redis
是單線程的,若是使用多個數據庫,那麼這些數據庫仍然是使用一個CPU
,彼此之間會受到影響.
多數據庫的使用方式,會在調試和運維不一樣業務的數據庫變得困難,假若有一個慢查詢存在,依然會影響其餘數據庫,這樣會使得別的業務方定位問題很是困難.
部分redis
的客戶端根本就不支持這種方式,及時支持,在開發的時候來回切換數字形式的數據庫,很容易弄亂.
flushdb/flushall
命令用於清除數據庫,二者的區別是:
flushdb
是清除當前數據庫的全部數據.
flushall
是清除實例的全部數據.
flushdb/flushall
命令能夠很是方便的清理數據,可是也帶來兩個問題:
flushdb/flushall
命令會將全部數據清除,一旦誤操做後果不堪設想.
若是當前數據庫鍵值數量比較多,flushdb/flushall
存在阻塞的可能.因此在使用flushdb/flushall
必定要當心謹慎.