在 Redis 數據類型 中我寫了 Redis 的 5 種數據類型和一些簡單的基礎命令. 這一章再寫一些更加深刻的命令.redis
字符串能夠存儲如下三種類型的值:segmentfault
整數的取值範圍和系統的長整數 (long integer) 的取值範圍相同 (在 322 位系統中, 整數就是 32 位有符號整數, 在 64 位系統中, 整數就是 64 位有符號整數), 而浮點數取值範圍和精度則與 IEEE 754 標準的雙精度浮點數 (double) 相同.數組
能夠經過給定一個任意的數值, 對存儲着整數或浮點數的字符串執行自增或自減操做, 在有須要的時候, Redis 還會將整數轉換成浮點數.
若是用戶對一個不存在的鍵或者一個保存了空串的鍵執行自增或自減操做, 那麼這個鍵的值看成是 0 來處理. 若是值沒法被解釋爲整數或者浮點數的字符串鍵執行自增或自減操做, Redis 就會返回一個錯誤.安全
INCR key-name 將鍵存儲的值加上 1, 返回執行完加 1 操做後的值. INCRBY key-name amount 將鍵存儲的值加上整數 amount . 返回加上 amount 後的值. DECR key-name 將鍵存儲的值減去 1, 返回執行完減 1 操做後的值. DECRBY key-name amount 將鍵存儲的值減去整數 amount. 返回減去 amount 後的值. INCRBYFLOAT key-name amount 將鍵存儲的值加上浮點數 amount. 返回加上 amount 後的值.
INCRBYFLOAT 若是 amount 爲 3.0 則會將浮點數轉換爲整數也就是 3.
APPEND key-name value 將值 value 追加到指定的 key-name 當前存儲的值得末尾, 返回追加後的長度. 若是不存在則同等於 key-name value. SETRANGE key-name offset value 字符串替換. 返回替換後的字符串長度. 從 offset 偏移量開始, 替換爲 value. GETRANGE key-name start end 從 start 開始到 end 結束, 返回指定部分的字符串.
GETRANGE 包含 start 和 end. 若是讀取字符串的時候, 超出字符串末尾的數據, 只會獲取到最後.
若是咱們要判斷指定 key 是否存在可使用 EXISTS
, 若 key 存在返回 1, 不然返回 0.服務器
LRANGE key-name start end 返回列表從 start 偏移量到 end 偏移量範圍內的全部元素. LTRIM key--name start end 對列表進行修剪, 只保留從 start 偏移量到 end 偏移量範圍內的元素.
BLPOP key-name [key-name] timeout
阻塞行爲函數
若是全部給定 key 都不存在或包含空列表, 那麼 BLPOP
命令將阻塞鏈接, 直到等待超時, 或有另外一個客戶端對給定 key 的任意一個執行 LPUSH key value [value …]
或 RPUSH key value [value …]
命令爲止.網站
超時參數 timeout
接受一個以秒爲單位的數字做爲值. 超時參數設爲 0
表示阻塞時間能夠無限期延長.scala
非阻塞行爲code
當 BLPOP
被調用時, 若是給定 key 內至少有一個非空列表, 那麼彈出遇到的第一個非空列表的頭元素, 並和被彈出元素所屬的列表的名字一塊兒, 組成結果返回給調用者.排序
當存在多個給定 key 時, BLPOP
按給定 key 參數排列的前後順序, 依次檢查各個列表.
假設如今有 job
、 command
和 request
三個列表, 其中 job
不存在, command
和 request
都持有非空列表. 考慮如下命令:
BLPOP job command request 0
BLPOP
保證返回的元素來自 command
, 由於它是按 」查找 job -> 查找 command -> 查找 request 「 這樣的順序, 第一個找到的非空列表.
redis> DEL job command request # 確保key都被刪除 (integer) 0 redis> LPUSH command "update system..." # 爲command列表增長一個值 (integer) 1 redis> LPUSH request "visit page" # 爲request列表增長一個值 (integer) 1 redis> BLPOP job command request 0 # job 列表爲空,被跳過,緊接着 command 列表的第一個元素被彈出。 1) "command" # 彈出元素所屬的列表 2) "update system..." # 彈出元素所屬的值
相同的 key 被多個客戶端同時阻塞
相同的 key 能夠被多個客戶端同時阻塞.
不一樣的客戶端被放進一個隊列中, 按『先阻塞先服務』(first-BLPOP, first-served)的順序爲 key 執行 BLPOP
命令.
客戶端1 執行參考以下:
blpop job 35
客戶端2 執行參考以下:
blpop job 30
key job 是不存在的, 客戶端1 超時時間爲 35 秒, 客戶端2 超時時間爲 30 秒. 執行結果以下:
客戶端2 先被打印, 而後在打印客戶端1, 由於客戶端2 的超時時間是 30 秒.
127.0.0.1:6379> blpop job 30 (nil) (30.04s) 127.0.0.1:6379> blpop job 35 (nil) (35.09s)
若是兩個客戶端的超時時間都爲 0
會是怎樣的呢?
這個時候就會像前面提到的, 按『先阻塞先服務』的順序爲 key 執行 BLPOP
命令.
RPOPLPUSH source-key dest-key
命令 RPOPLPUSH
在一個原子時間內, 執行如下兩個動做:
source-key
中的最後一個元素(尾元素)彈出, 並返回給客戶端.source-key
彈出的元素插入到列表 dest-key
, 做爲 dest-key
列表的的頭元素.若是 source-key
不存在, 值 nil
被返回, 而且不執行其餘動做.
若是 source-key
和 dest-key
相同(同一個key), 則列表中的表尾元素被移動到表頭, 並返回該元素, 能夠把這種特殊狀況視做列表的旋轉(rotation)操做.
模式: 安全的隊列
Redis 的列表常常被用做隊列(queue), 用於在不一樣程序之間有序地交換消息(message). 一個客戶端經過 LPUSH key value [value …]
命令將消息放入隊列中, 而另外一個客戶端經過 RPOP key
或者 BRPOP key [key …] timeout
命令取出隊列中等待時間最長的消息.
不幸的是, 上面的隊列方法是『不安全』的, 由於在這個過程當中, 一個客戶端可能在取出一個消息以後崩潰, 而未處理完的消息也就所以丟失.
使用 RPOPLPUSH
命令(或者它的阻塞版本 BRPOPLPUSH source destination timeout
` )能夠解決這個問題.
由於它不只返回一個消息, 同時還將這個消息添加到另外一個備份列表當中, 若是一切正常的話, 當一個客戶端完成某個消息的處理以後, 能夠用 LREM key count value
命令將這個消息從備份表刪除.
最後, 還能夠添加一個客戶端專門用於監視備份表, 它自動地將超過必定處理時限的消息從新放入隊列中去(負責處理該消息的客戶端可能已經崩潰), 這樣就不會丟失任何消息了.
模式: 循環列表
經過使用相同的 key 做爲 RPOPLPUSH
命令的兩個參數, 客戶端能夠用一個接一個地獲取列表元素的方式, 取得列表的全部元素, 而沒必要像 LRANGE key start stop
命令那樣一會兒將全部列表元素都從服務器傳送到客戶端中.
以上的模式甚至在如下的兩個狀況下也能正常工做:
這個模式使得咱們能夠很容易實現這樣一類系統: 有 N 個客戶端, 須要接二連三地對一些元素進行處理, 並且處理的過程必須儘量地快.
一個典型的例子就是服務器的監控程序: 它們須要在儘量短的時間內, 並行地檢查一組網站, 確保它們的可訪問性.
注意, 使用這個模式的客戶端是易於擴展(scala)且安全(reliable)的, 由於就算接收到元素的客戶端執行失敗, 元素仍是保存在列表裏面, 不會丟失, 等到下個迭代來臨的時候, 別的客戶端又能夠繼續處理這些元素了.
SCARD key-name 返回集合 key 的基數. 當 key 不存在時, 返回 0.
隨機返回元素
SRANDMEMBER key-name [count]
若是命令執行時, 只提供了 key 參數, 那麼返回集合中的一個隨機元素.
count
參數分爲以下兩種:
SPOP key-name [count]
移除並返回集合中的一個隨機元素. 當 key 不存在或 key 是空集時, 返回 nil
.
組合或處理多個集合
SMOVE source-key dest-key member
若是 source-key
集合不存在或不包含指定的 member
元素, 則 SMOVE
命令不執行任何操做, 僅返回 0(零). 不然, member
` 元素從 source-key
集合中被移除, 並添加到 dest-key
集合中.
當 dest-key
集合已經包含 member
元素時, SMOVE
命令只是簡單地將 source-key
集合中的 member
元素刪除.
SDIFF key [key …]
返回那些存在於第一個集合, 但不存在於其餘集合中的元素.
不存在的 key 被視爲空集.
SDIFFSTORE destination key [key …]
這個命令的做用和 SDIFF key [key …]
相似, 但它將結果保存到 destination
集合, 而不是簡單地返回結果集.
若是 destination
集合已經存在, 則將其覆蓋.
destination
能夠是 key 自己.
返回結果集中的元素數量.
SINTER key [key …]
返回存在全部集合中的元素.
SUNION key [key …]
返回一個集合的所有成員, 該集合是全部給定集合的並集.
不存在的 key 被視爲空集.
HMSET key field value [field value …] 設置多個鍵值. HVALS key 返回全部的值. HKEYS key 返回全部的鍵. HGETALL key 返回全部的鍵值.
HMGET key field [field …]
返回哈希表 key 中, 一個或多個給定域的值.
若是給定的域不存在於哈希表, 那麼返回一個 nil 值.
由於不存在的 key 被看成一個空哈希表來處理, 因此對一個不存在的 key 進行 HMGET 操做將返回一個只帶有 nil 值的表.
HEXISTS hash field
檢查給定域 field 是否存在於哈希表 hash 當中. 給定域存在時返回 1, 在給定域不存在時返回 0.
HINCRBY key field increment
爲哈希表 key 中的域 field 的值加上增量 increment.
增量也能夠爲負數, 至關於對給定域進行減法操做.
若是 key 不存在, 一個新的哈希表被建立並執行 HINCRBY 命令.
若是域 field 不存在, 那麼在執行命令前, 域的值被初始化爲 0.
對一個儲存字符串值的域 field 執行 HINCRBY 命令將形成一個錯誤.
本操做的值被限制在 64 位(bit)有符號數字表示以內.
HINCRBYFLOAT key field increment
爲哈希表 key 中的域 field 加上浮點數增量 increment.
若是哈希表中沒有域 field, 那麼 HINCRBYFLOAT
會先將域 field 的值設爲 0, 而後再執行加法操做.
若是鍵 key 不存在, 那麼 HINCRBYFLOAT
會先建立一個哈希表, 再建立域 field, 最後再執行加法操做.
當如下任意一個條件發生時, 返回一個錯誤:
increment
不能解釋 (parse) 爲雙精度浮點數(double precision floating point number).ZADD key score member [[score member] [score member] …]
將一個或多個 member
元素及其 score
值加入到有序集 key 當中.
若是某個 member
已是有序集的成員, 那麼更新這個 member
的 score
值, 並經過從新插入這個 member
元素, 來保證該 member
在正確的位置上.
score
值能夠是整數值或雙精度浮點數.
若是 key
不存在, 則建立一個空的有序集並執行 ZADD
操做.
當 key
存在但不是有序集類型時, 返回一個錯誤.
返回被成功添加的新成員的數量, 不包括那些被更新的, 已經存在的成員.
ZREM key member [member …] 移除有序集 key 中的一個或多個成員, 不存在的成員將被忽略. 被成功移除的成員的數量, 不包括被忽略的成員. ZCARD key 當 key 存在且是有序集類型時, 返回有序集的基數. 當 key 不存在時, 返回 0. ZCOUNT key min max 返回有序集 key 中, score 值在 min 和 max 之間的成員的數量. ZRANK key member 返回有序集 key 中成員 member 的排名. 其中有序集成員按 score 值遞增(從小到大)順序排列. ZREVRANK key member 返回有序集 key 中成員 member 的排名.其中有序集成員按 score 值遞減(從大到小)排序. ZSCORE key member 返回有序集 key 中, 成員 member 的 score 值. 若是 member 元素不是有序集 key 的成員, 或 key 不存在, 返回 nil.
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集 key 中, 全部 score 值介於 min 和 max 之間(包括等於 min 或 max )的成員. 有序集成員按 score 值遞增(從小到大)次序排列.
具備相同 score 值的成員按字典序(lexicographical order)來排列(該屬性是有序集提供的, 不須要額外的計算).
可選的 LIMIT 參數指定返回結果的數量及區間(就像SQL中的 SELECT LIMIT offset, count ), 注意當 offset 很大時, 定位 offset 的操做可能須要遍歷整個有序集.
可選的 WITHSCORES 參數決定結果集是單單返回有序集的成員, 仍是將有序集成員及其 score 值一塊兒返回.
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 從大到小.
交集和並集
ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
計算給定的一個或多個有序集的並集, 其中給定 key 的數量必須以 numkeys 參數指定, 並將該並集(結果集)儲存到 destination.
默認狀況下, 結果集中某個成員的 score 值是全部給定集下該成員 score 值之和.
WEIGHTS
使用 WEIGHTS 選項, 你能夠爲每一個給定有序集分別指定一個乘法因子(multiplication factor), 每一個給定有序集的全部成員的 score 值在傳遞給聚合函數(aggregation function)以前都要先乘以該有序集的因子.
若是沒有指定 WEIGHTS 選項, 乘法因子默認設置爲 1.
AGGREGATE
使用 AGGREGATE 選項, 你能夠指定並集的結果集的聚合方式.
默認使用的參數 SUM
, 能夠將全部集合中某個成員的 score 值之和做爲結果集中該成員的 score 值; 使用參數 MIN
, 能夠將全部集合中某個成員的最小 score 值做爲結果集中該成員的 score 值; 而參數 MAX
則是將全部集合中某個成員的最大 score 值做爲結果集中該成員的 score 值.
ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
計算給定的一個或多個有序集的交集, 其中給定 key 的數量必須以 numkeys 參數指定, 並將該交集(結果集)儲存到 destination.
默認狀況下, 結果集中某個成員的 score 值是全部給定集下該成員 score 值之和.
並集和交集的主要區別
咱們如今有三個有序集合, 以下:
ZRANGE test1 0 -1 WITHSCORES "z" "1" "a" "2" "e" "3" ZRANGE test2 0 -1 WITHSCORES "a" "1" ZRANGE test3 0 -1 WITHSCORES "r" "2"
使用交集結果以下:
ZINTERSTORE destination 3 test1 test2 test3 (integer) 0 ZINTERSTORE destination 2 test1 test2 (integer) 1
test1 和 test2 中都存在成員是 "a" 的數據, 因此當咱們執行第二條命令的時候, "a" 的成員被添加到了 destination 有序集中, 而且分值爲 3(默認使用 SUM
).
而執行第一條命令時, 並沒添加到 destination 有序集中. 緣由是 test3 中沒有成員 "a".
交集只會將給定有序集中的相同成員添加到 destination 有序集中. 並集和交集不一樣, 只要某個成員存在於任意一個給定的有序集中, 都會被添加到 destination 有序集中.