redis學習筆記(四):鍵管理

本章將按照單個鍵,遍歷鍵,數據庫管理三個維度對一些通用命令進行介紹.java

1. 單鍵管理

針對單個鍵的命令,前面幾節已經介紹過一部分了,例如type,del,object,exists,expire等,下面介紹幾個重要命令.node

1) 鍵重命名
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的可能性,這點不要忽視.數據庫

  • 若是renamerenamenx中的keynewkey若是是相同的,在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
2) 隨機返回一個鍵
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
3) 鍵過時

除了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命令能夠設置鍵的秒級時間戳,例如若是須要將鍵hello2017-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的組合,不可是原子執行,同時減小了一次網絡通信時間.

2.遷移鍵

遷移鍵功能很是重要,由於有時候咱們只想把部分數據由一個redis遷移到另外一個redis(例如從生產環境遷移到測試環境),redis發展歷程中提供了move,dump+restoremigrate三組遷移鍵的方法.

1) move
move key db

clipboard.png

如上圖所示,move命令因爲在redis內部進行數據遷移,redis內部能夠有多個數據庫,move key db就是把指定的鍵從源數據庫移動到目標數據庫中,但不建議在生產環境使用.

2) dump+restore
dump key
    restore key ttl value

dump+restore能夠實現不一樣的redis實例之間進行數據遷移的功能,整個遷移的過程分爲兩步:

  1. 在源redis下使用dump命令將鍵值序列化,格式採用的是RDB格式.

  2. 在目標redis上,restore命令將上面序列化的的值進行復原,其中ttl參數表明過時時間,若是ttl=0表明沒有過時時間.

有關dump+restore有兩點須要注意:第一:整個遷移過程並不是原子性,而是經過客戶端分步完成的.第二:遷移過程是開啓了兩個客戶端鏈接,因此dump的結果不是在源redis和目標redis之間進行傳輸的.

3) migrate
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實例之間

3.遍歷鍵

redis提供了兩個命令遍歷全部的鍵,分別是keysscan.

1) 全量遍歷鍵
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]表明匹配110的任意數字.

  • \x用來轉義,例如要匹配星號,問號須要進行轉義.

若是redis包含了大量的鍵,執行keys命令極可能會形成redis阻塞,全部通常建議不要在生產環境下使用keys命令,但有時候確實有遍歷鍵的需求怎麼辦,能夠在一下三種狀況下使用:

  • 在一個不對外提供服務的redis從節點上執行,這樣不會阻塞到客戶端的請求.

  • redis實例下的鍵總數比較少,可執行此命令.

  • 使用scan命令漸進式的遍歷全部鍵,能夠有效防止阻塞.

2) 漸進式遍歷

redis2.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"

4.數據庫管理

redis提供了幾個面向redis數據的操做,他分別是dbsize,select,flushdb,flushall命令.

1.切換數據庫
select dbIndex

許多關係型數據庫,例如MySQL支持在一個實例下有多個數據庫存在,可是與關係型數據庫用字符來區分不一樣數據庫名不一樣,redis只是用數字做爲多個數據庫的實現.redis默認配置中是有16個數據庫:

databases 16

redis 3.0中已經開始逐漸弱化這個功能,例如redis的分佈式實現redis cluster只容許使用0號數據庫,只不過爲了向下兼容老版本的數據庫功能,該功能沒有徹底廢棄掉.

廢棄多數據庫的緣由:

  • redis是單線程的,若是使用多個數據庫,那麼這些數據庫仍然是使用一個CPU,彼此之間會受到影響.

  • 多數據庫的使用方式,會在調試和運維不一樣業務的數據庫變得困難,假若有一個慢查詢存在,依然會影響其餘數據庫,這樣會使得別的業務方定位問題很是困難.

  • 部分redis的客戶端根本就不支持這種方式,及時支持,在開發的時候來回切換數字形式的數據庫,很容易弄亂.

2.flushdb/flushall

flushdb/flushall命令用於清除數據庫,二者的區別是:

  1. flushdb是清除當前數據庫的全部數據.

  2. flushall是清除實例的全部數據.

flushdb/flushall命令能夠很是方便的清理數據,可是也帶來兩個問題:

  • flushdb/flushall命令會將全部數據清除,一旦誤操做後果不堪設想.

  • 若是當前數據庫鍵值數量比較多,flushdb/flushall存在阻塞的可能.因此在使用flushdb/flushall必定要當心謹慎.

相關文章
相關標籤/搜索