在redis裏面,字符串能夠存儲如下3中類型的值python
用戶能夠對存儲着整數或者浮點數的字符串執行自增或者自減的操做,在有須要的時候,Redis還會將整數轉爲浮點數。redis
整數的取值範圍與系統的位數相關(32位或64位)。數據庫
浮點數的取值範圍和精度則與雙精度浮點數(double)相同,64位(11位階碼,1位符號位,剩下52位尾數)。服務器
經常使用的命令以下:網絡
1. 數據操做app
2. 自增自減命令函數
incr key-name
將鍵存儲的值加1。性能
decr key-name
將鍵存儲的值減1。測試
incrby key-name amount
將鍵存儲的值加上整數amount操作系統
decrby key-name amount
將鍵存儲的值減去整數amount。
incrbyfloat key-name amount
將鍵存儲的值加上浮點數amount,這個命令在Redis2.6以上的版本可用
若是用戶對一個不存在的鍵或者存儲了空串的鍵執行自增或者自減操做,redis會將這個鍵值當作0來處理。
若是用戶對一個沒法解釋爲整數或浮點數的字符串進行自增或自減,redis會向用戶返回一個錯誤。
3. 處理子串和二進制位的命令
append key-name value
將value追加到指定鍵key-name當前存儲的值的末尾
getrange key-name start end
獲取一個由偏移量start至偏移量end範圍內全部字符組成的子串,包括start和end在內(由之前的substr更名而來)
setrange key-name offset value
將從offset偏移量開始的子串設置爲給定值
getbit key-name offset
將字節串看做是二進制位串,並返回位串中偏移量爲offset的二進制位的值。
setbit key-name offset value
將字節串看做是二進制位串,並將位串中偏移量爲offset的二進制的值設置爲value
bitcount key-name [start end]
統計二進制位串裏面值爲1的二進制位的數量,若是給定了可選的start偏移量和end偏移量,那麼只對偏移量指定範圍內的二進制位進行統計。
bitop operation dest-key key-name [key-name...]
對一個或多個二進制位串執行包括並(and)、或(or)、異或(xor)、非(not)在內的任意一種按位運算操做,並將計算得出的結果保存在dest-key鍵裏面。
在使用setrange或者setbit對字符串進行寫入的時候,若是字符串當前的長度不能知足寫入要求,redis會自動使用空字節(null)來將字符串擴展至所需的長度,而後才進行寫入操做。
在使用getrange讀取字符串時,超出字符串末尾的數據會被視爲空串,而在使用getbit讀取二進制位串的時候,超出字符串末尾的二進制位會被視爲0。
一個鏈表,鏈表上的每一個節點都包含一個字符串,一個列表結構能夠有序地存儲多個字符串。
列表容許用戶從序列的兩端推入或者彈出元素,獲取列表元素以及執行各類常見的列表操做。
1. 經常使用的列表命令
rpush key-name value [value ...]
將一個或多個值推入列表的右端。
lpush key-name value [value ...]
將一個或多個值推入列表的左端。
rpop key-name
移除或返回列表最右端的元素。
lpop key-name
移除或返回列表最左端的元素。
lindex key-name offset
返回列表中偏移量爲offset的元素。
lrange key-name start end
返回列表從start偏移量到end偏移量範圍內的全部元素,其中偏移量爲start和偏移量爲end的元素也會包含在被返回的元素以內。
ltrim key-name start end
對列表進行修剪,只保留從start偏移量到end偏移量範圍內的元素,其中偏移量爲start和偏移量爲end的元素也會被保留。
組合使用ltrim和lrange能夠構建出一個在功能上相似於lpop和rpop,可是卻可以一次返回並彈出多個元素的操做。
2. 阻塞式的列表彈出命令以及在列表之間移動元素的命令
blpop key-name [key-name...] timeout
從第一個非空列表彈出最左端的元素,或者在timeout秒以內阻塞並等待可彈出的元素出現。
brpop key-name [key-name...] timeout
從第一個非空列表彈出最右端的元素,或者在timeout秒以內阻塞並等待可彈出的元素出現。
rpoplpush source-key dest-key
從source-key列表中彈出位於最右端的元素,而後將這個元素推入dest-key列表的最左端,並向用戶返回這個元素。
brpoplpush source-key dest-key timeout
從source-key列表中彈出位於最右端的元素,而後將這個元素推入dest-key列表中的最左端,並向用戶返回這個元素;若是source-key爲空,那麼在timeout秒以內阻塞並等待可彈出的元素。
對於阻塞彈出命令和彈出並推入命令,最多見的用例就是消息傳遞(messageing)和任務隊列(task queue)。
Redis的集合以無序的方式來存儲多個各不相同的元素,用戶能夠快速地對集合執行添加元素的操做,移除元素以及檢查一個元素是否存在於集合中。
1. 經常使用的集合命令
sadd key-name item [item ...]
將一個或多個元素添加到集合中,並返回被添加元素當中本來並不存在於集合裏面的元素數量。
srem key-name item [item ...]
從集合中移除一個或多個元素,並返回被移除元素的數量
sismember key-name item
檢查元素item是否存在於集合key-name裏面,
scard key-name
返回集合包含的元素的數量。
smembers key-name
返回集合所包含的全部元素。
srandmember key-name [count]
從集合裏面隨機地返回一個或多個元素。當count爲正數,命令返回的隨機元素不會重複,當count爲負數,命令返回的隨機元素可能會出現重複。
spop key-name
隨機地移除集合中的一個元素,並返回被移除的元素
smove source-key dest-key item
若是集合source-key包含元素item,那麼從集合source-key裏面移除元素item,並將元素item添加到集合dest-key裏面。若是item被成功移除,那麼命令返回1,不然命令返回0。
2. 用於組合和處理多個集合的命令
sdiff key-name [key-name ...]
返回存在於第一個集合但不存在與其餘集合中的元素(數學上的差集運算)
sdiffstore dest-key key-name [key-name ...]
將那些存在於第一個集合但並不存在於其餘集合中的元素(數學上的差集運算)存儲到dest-key鍵裏面。
sinter key-name [key-name ...]
返回那些同時存在於全部集合中的元素(數學上的交集運算)
sinterstore dest-key key-name [key-name ...]
將那些同時存在於全部集合的元素(數學上的交集運算)存儲到dest-key鍵裏面
sunion key-name [key-name ...]
返回那些至少存在於一個集合中的元素(數學上的並集計算)
sunionstore dest-key key-name [key-name ...]
將那些至少存在於一個集合中的元素(數學上的並集計算)存儲到dest-key鍵裏面
Redis的散列是容許用戶將多個鍵值對存儲到一個Redis鍵中,適合將一些相關的數據存儲在一塊兒,能夠將數據彙集看做是關係型數據庫中的行,或者文檔數據庫中的文檔。
1. 用於添加刪除鍵值對的散列操做
hget key-name key
從散列裏面獲取一個鍵的值
hmget key-name key [key ...]
從散列裏面獲取一個或多個鍵的值
hset key-name key value
爲散列裏面的一個鍵設置值
hmset key-name key value [key vaule ...]
爲散列裏面的一個或多個鍵設置值
hdel key-name key [key ..]
刪除散列裏面一個或多個鍵值對,返回成功找到並刪除的鍵值對數量
hlen key-name
返回散列包含的鍵值對數量
hmget和hmset批量處理多個鍵值既給用戶帶來方便又減小了命令的調用次數以及客戶端與redis之間的通訊往返次數來提高redis的性能。
2. redis散列的高級特性
hexists key-name key
檢查給定鍵是否存在於散列中
hkeys key-name
獲取散列包含的全部鍵
hvals key-name
獲取散列包含的全部值
hgetall key-name
獲取散列包含的全部鍵值對
hincrby key-name key increment
將鍵key存儲的值加上整數increment,對散列中一個還沒有存在的鍵執行自增操做時,redis會將鍵的值當作0來處理。
hincrbyfloat key-name key increment
將鍵key存儲的值加上浮點數increment
儘管有hgetall存在,但hkeys和hvals也是很是有用的:若是散列包含的值很是大,那麼能夠先使用hkeys取出散列包含的全部鍵,而後再使用HGET一個接一個地取出鍵的值,從而避免由於一次獲取多個大致積的值而致使服務器阻塞。
有序集合存儲着成員與分值之間的映射,而且提供了分值處理命令,以及根據分值大小有序地獲取或掃描成員和分值的命令。
1. 有序集合經常使用命令
zadd key-name score member [score member ...]
將帶有給定分值的成員添加到有序集合裏面,注意這裏是先輸入分值再輸入成員,而python客戶端執行zadd命令是先輸入成員後輸入分值。
zrem key-name member [member ...]
從有序集合裏面移除給定的成員,並返回被移除成員的數量
zcard key-name
返回有序集合包含的成員數量
zincrby key-name increment member
將member成員的分值加上increment
zcount key-name min max
返回分值介於min和max之間的成員數量
zrank key-name member
返回成員member在有序集合中的排名,排名以0開始
zscore key-name member
返回成員member的分值
zrange key-name start stop [withscores]
返回有序集合中排名介於start和stop之間的成員,若是給定了可選的withscores選項,那麼命令會將成員的分值也一併返回
2. 有序集合的範圍型數據獲取命令和範圍型數據刪除命令,以及並集命令和交集命令
zrevrank key-name member
返回有序集合成員member的排名,成員按照分值從大到小排列
zrevrange key-name start stop [withscores]
返回有序集合給定排名範圍內的集合,成員按照分值從大到小排列
zrangebyscore key min max [withscores] [limit offset count]
返回有序集合中分值介於min和max之間的全部成員
zrevrangebyscore key max min [withscores] [limit offset count]
獲取有序集合中分值介於min和max之間的全部成員,並按照分值從大到小的順序來返回它們
zremrangebyrank key-name start stop
移除有序集合中排名介於start和stop之間的全部成員
zremrangebyscore key-name min max
移除有序集合中分值介於min和max之間的全部成員
zinterscore dest-key key-count key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
對給定的有序集合執行相似於集合的交集運算,並將結果保存在dest-key中。默認使用的彙集函數是sum,能夠根據aggregate的參數修改彙集函數。
zunionscore dest-key key-count key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
對給定的有序集合執行相似於集合的並集運算,並將結果保存在dest-key中。默認使用的彙集函數是sum,能夠根據aggregate的參數修改彙集函數。
對於,用戶能夠將集合做爲輸入傳給zinterscore和zunionscore,命令會將集合看做是成員分值全爲1的有序集合來處理。
發佈與訂閱(又稱pub/sub)的特色是訂閱者(listener)負責訂閱頻道(channel),發送者(publisher)負責向頻道發送二進制字符串消息(binary string message)。每當有消息被髮送至給定頻道時,頻道的全部訂閱者都會接收到消息。
也能夠把頻道看做是電臺,其中訂閱者能夠同時收聽多個電臺,而發送者則能夠在任何電臺發送消息。
1.發佈與訂閱命令
subscribe channel [channel ...]
訂閱給定的一個或多個頻道
unsubscribe [channel [channel ...]]
退訂給定的一個或多個頻道,若是執行時沒有給定任何頻道,那麼退訂全部頻道
publish channel message
向給定頻道發送消息
psubcribe pattern [pattern ...]
訂閱與給定模式相匹配的全部頻道
punsubcribe [pattern [pattern ...]]
退訂給定的模式,若是執行時沒有給定任何模式,那麼退訂全部模式
示例代碼以下:
import time import threading import unittest """ 發佈者 """ def publisher(conn, n): # 在剛開始執行時先休眠,讓訂閱者有足夠的時間來鏈接服務器並監聽消息 time.sleep(1) for i in xrange(n): conn.publish('channel', i) # 發佈消息以後進行短暫的休眠,讓消息能夠一條一條地出現 time.sleep(1) """ 發佈訂閱模式 """ def runPubsub(conn): # 啓動發送者線程發送3條消息 threading.Thread(target=publisher, args=(conn,3,)).start() # 建立發佈與訂閱對象,並讓它訂閱給定的頻道 pubsub = conn.pubsub() pubsub.subscribe(['channel']) count = 0 # 經過遍歷函數pubsub.listen()執行結果來監聽訂閱消息 for item in pubsub.listen(): print item count += 1 if count == 4: # 在接收到一條訂閱反饋消息和三條發佈者發送消息以後,執行退訂操做,中止監聽新消息 pubsub.unsubscribe() # 客戶端在接收到退訂反饋消息以後就再也不接收消息 if count == 5: break """ 測試 """ class TestRedisPubSub(unittest.TestCase): def setUp(self): import redis self.conn = redis.Redis(db=15) def tearDown(self): del self.conn print print def testRunPubsub(self): runPubsub(self.conn) if __name__ == '__main__': unittest.main()
雖然redis的發佈訂閱模式頗有用,但咱們比較少用,主要緣由有如下:
(1)與redis的穩定性有關。對於舊版redis來講,若是客戶端訂閱了某個或某些頻道,讀取的消息速度不夠快,不斷積壓的消息會使redis輸出緩衝區的體積變得愈來愈大,致使redis速度變慢甚至直接崩潰,也可能致使操做系統強制殺死進程,或者操做系統直接不可用。
新版的redis會自動斷開不符合client-output-buffer-limit pubsub配置選項要求的訂閱客戶端。
(2)和數據傳輸的可靠性有關。任何網絡系統在執行操做時都有可能會遇到斷線狀況,若是客戶端在執行訂閱操做的過程當中斷線,那麼客戶端將丟失在斷線期間發送的全部消息。
若是喜歡簡單易用的pushlish命令和subscribe命令,而且能夠承擔可能會丟失一部分數據的風險,那麼也能夠繼續使用redis提供的發佈和訂閱特性。
這節的命令能夠用於處理多種類型的數據。
sort source-key by pattern[get pattern [get pattern...]]asc|desc[store dest-key]
根據給定的選項,對輸入的列表,集合或者有序集合進行排序,而後返回或者存儲排序的結果
sort命令能夠根據降序而不是默認的升序來排序元素,將元素看作是數字來排序,或者將元素看作是二進制字符串來排序;使用被排序元素以外的其餘值做爲權重來進行排序,甚至能夠從輸入的列表,集合,有序集合之外的其餘地方進行取值。
如如下代碼演示了經過sort將散列存儲的數據做爲權重進行排序,以及怎樣獲取並返回散列存儲的數據:
# 首先將一些元素添加到列表裏面 >>> conn.rpush('sort-input', 23, 15, 110, 7) 4 # 根據數字大小對元素進行排序 >>> conn.sort('sort-input') ['7','15','23','110'] # 根據字母表順序對元素進行排序 >>> conn.sort('sort-input', alpha=True) ['110','15','23','7'] # 添加一些用於執行排序操做和獲取操做的附加數據 >>> conn.hset('d-7', 'field', 5) >>> conn.hset('d-15', 'field', 1) >>> conn.hset('d-23', 'field', 9) >>> conn.hset('d-110', 'field', 3) # 將散列的域field用做權重,對sort-input列表進行排序 >>> conn.sort('sort-input', by='d-*->field') ['15','110','7','23'] # 獲取外部數據,並將它們用做命令的返回值,而不是返回被排序的數據 >>> conn.sort('sort-input', by='d-*->field', get='d-*->field') ['1','3','5','9']
Redis的基本事務須要用到multi命令和exec命令,這種事務可讓一個客戶端在不被其餘客戶端打斷的狀況下執行多個命令。
被multi和exec命令包圍的全部命令會一個接一個地執行,直到全部命令都執行完畢爲止。當一個事務執行完畢後,redis纔會處理其餘客戶端的命令。
當redis從一個客戶端那裏接收到multi命令時,Redis會將這個客戶端以後發送的全部命令都放在一個隊列裏面,直到這個客戶端發送exec命令爲止,而後redis就會在不被打斷的狀況下,一個接一個地執行存儲在隊列裏面的命令。
redis事務在python客戶端上面是由pipeline實現的,對鏈接對象調用pipeline方法建立一個事務,在一切正常的狀況下,客戶端會自動地使用multi和exec包裹起用戶輸入的多個命令,此外,爲了減小redis與客戶端之間的通訊往返次數,提高執行多個命令時的性能,python的redis客戶端會存儲起事務包含的多個命令,而後在事務執行時一次性將全部命令都發送給redis。
注意,redis要在接收到exec命令以後,纔會執行那些位於multi和exec之間的入隊命令。
示例代碼以下:
def trans(conn): # 建立一個事務型流水線對象 pipeline = conn.pipeline() # 把計數器的自增操做放入隊列 pipeline.incr('trans:') time.sleep(.1) # 把計數器的自減操做放入隊列 pipeline.incr('trans:', -1) # 執行被事務包裹的命令,並打印自增操做的執行結果 print pipeline.execute()[0] # 測試 for i in xrange(3): threading.Thread(target=trans, args=(self.conn,)).start() time.sleep(.5)
在使用Redis存儲數據的時候,有些數據在某個時間點以後就再也不有用,用戶可使用DEL命令顯示地刪除那些無用數據,也能夠經過redis的過時時間特性來讓一個鍵在給定的時限以後自動被刪除。
鍵過時命令只能爲整個鍵設置過時時間,而沒辦法爲鍵裏面的單個元素設置過時時間,爲了解決這個問題,可使用存儲時間戳的有序集合來實現針對單個元素的過時操做。
persist key-name
移除鍵的過時時間
ttl key-name
查看給定鍵距離過時還有多少秒
expire key-name seconds
讓給定鍵在指定的秒數以後過時
expireat key-name timestamp
將給定鍵的過時時間設置爲給定的unix時間戳
pttl key-name
查看給定鍵距離過時時間還有多少毫秒,這個命令在redis2.6或以上版本可用
pexpire key-name milliseconds
讓給定鍵在指定的豪秒數以後過時,這個命令在redis2.6或以上版本可用
pexpireat key-name timestamp-milliseconds將一個毫秒級精度的unix時間戳設置爲給定鍵的過時時間,這個命令在redis2.6或以上版本