Redis Python
Python操作Redis
安裝Python使用Redis的庫(kù)
sudo pip install redis or sudo easy_install redis or 源碼安裝 詳見(jiàn):https://github.com/WoLpH/redis-py1.1 操作模式
redis-py提供兩個(gè)類(lèi)Redis和StrictRedis用于實(shí)現(xiàn)Redis的命令,StrictRedis用于實(shí)現(xiàn)大部分官方的命令,并使用官方的語(yǔ)法和命令,Redis是StrictRedis的子類(lèi),用于向后兼容舊版本的redis-py。
#!/usr/bin/env python # -*- coding:utf-8 -*-import?redis# r?=?redis.Redis(host='10.211.55.4', port=6379) r?=?redis.StrictRedis(host='10.211.55.4', port=6379, password='123456') # 推薦使用StrictRedis r.set('foo',?'Bar') print?r.get('foo')1.2 連接池
redis-py使用connection pool來(lái)管理對(duì)一個(gè)redis server的所有連接,避免每次建立、釋放連接的開(kāi)銷(xiāo)。默認(rèn),每個(gè)Redis實(shí)例都會(huì)維護(hù)一個(gè)自己的連接池。可以直接建立一個(gè)連接池,然后作為參數(shù)Redis,這樣就可以實(shí)現(xiàn)多個(gè)Redis實(shí)例共享一個(gè)連接池。
import?redispool?=?redis.ConnectionPool(host='10.211.55.4', port=6379) r?=?redis.Redis(connection_pool=pool) r.set('foo',?'Bar') print?r.get('foo')三、操作
3.1 String操作
Redis中的String在內(nèi)存中按照一個(gè)name對(duì)應(yīng)一個(gè)value來(lái)存儲(chǔ)。
3.1.1 分布式鎖
setnx(name, value) # 設(shè)置值,如果 name 不存在才能設(shè)置成功,返回True,如果 name 存在,設(shè)置失敗,返回 False3.1.2 操作?
set(name, value, ex=None, px=None, nx=False, xx=False) # 在Redis中設(shè)置值,默認(rèn),不存在則創(chuàng)建,存在則修改# ex,過(guò)期時(shí)間(秒)# px,過(guò)期時(shí)間(毫秒)# nx,如果設(shè)置為T(mén)rue,則只有name不存在時(shí),當(dāng)前set操作才執(zhí)行# xx,如果設(shè)置為T(mén)rue,則只有name存在時(shí),崗前set操作才執(zhí)行setex(name, value, time) # 設(shè)置值,設(shè)置過(guò)期時(shí)間# time,過(guò)期時(shí)間(數(shù)字秒 或 timedelta對(duì)象)psetex(name, time_ms, value) # 設(shè)置值# time_ms,過(guò)期時(shí)間(數(shù)字毫秒 或 timedelta對(duì)象)mset(*args, **kwargs) # 批量設(shè)置值 # 如:mset(k1='v1', k2='v2') # 或:mset({'k1':?'v1',?'k2':?'v2'})get(name) # 獲取值mget(keys, *args) # 批量獲取 # 如:mget('ylr',?'wupeiqi') # 或:mget(['ylr',?'wupeiqi'])getset(name, value) # 設(shè)置新值并獲取原來(lái)的值getrange(name, start, end) # 獲取子序列(根據(jù)字節(jié)獲取,非字符)# name,Redis 的 name# start,起始位置(字節(jié))# end,結(jié)束位置(字節(jié))# 如: "abcdefg" ,0-3表示 "abcd"setrange(name, offset, value) # 修改字符串內(nèi)容,從指定字符串索引開(kāi)始向后替換(新值太長(zhǎng)時(shí),則向后添加)# offset,字符串的索引,字節(jié)(一個(gè)漢字三個(gè)字節(jié))# value,要設(shè)置的值setbit(name, offset, value) # 對(duì)name對(duì)應(yīng)值的二進(jìn)制表示的位進(jìn)行操作# name,redis的name# offset,位的索引(將值變換成二進(jìn)制后再進(jìn)行索引)# value,值只能是 1 或 0注:如果在Redis中有一個(gè)對(duì)應(yīng): n1 = "foo",那么字符串foo的二進(jìn)制表示為:01100110?01101111?01101111 所以,如果執(zhí)行 setbit('n1',?7,?1),則就會(huì)將第7位設(shè)置為1,那么最終二進(jìn)制則變成?01100111?01101111?01101111,即:"goo"擴(kuò)展,轉(zhuǎn)換二進(jìn)制表示:source = "武沛齊"source?=?"foo"for?i?in?source:num?=?ord(i)print?bin(num).replace('b','')特別的,如果source是漢字?"武沛齊"怎么辦? 答:對(duì)于utf-8,每一個(gè)漢字占?3?個(gè)字節(jié),那么?"武沛齊"?則有?9個(gè)字節(jié) 對(duì)于漢字,for循環(huán)時(shí)候會(huì)按照 字節(jié) 迭代,那么在迭代時(shí),將每一個(gè)字節(jié)轉(zhuǎn)換 十進(jìn)制數(shù),然后再將十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制 11100110?10101101?10100110?11100110?10110010?10011011?11101001?10111101?10010000 -------------------------- ----------------------------- -----------------------------武 沛 齊getbit(name, offset) # 獲取name對(duì)應(yīng)的值的二進(jìn)制表示中的某位的值 (0或1)bitcount(key, start=None, end=None) # 獲取name對(duì)應(yīng)的值的二進(jìn)制表示中 1 的個(gè)數(shù)# key,Redis的name# start,位起始位置# end,位結(jié)束位置bitop(operation, dest, *keys) # 獲取多個(gè)值,并將值做位運(yùn)算,將最后的結(jié)果保存至新的name對(duì)應(yīng)的值# operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(異或)# dest, 新的Redis的name# *keys,要查找的Redis的name 如:bitop("AND",?'new_name',?'n1',?'n2',?'n3') # 獲取Redis中n1,n2,n3對(duì)應(yīng)的值,然后講所有的值做位運(yùn)算(求并集),然后將結(jié)果保存 new_name 對(duì)應(yīng)的值中strlen(name) # 返回name對(duì)應(yīng)值的字節(jié)長(zhǎng)度(一個(gè)漢字3個(gè)字節(jié))incr(self, name, amount=1) # 自增 name對(duì)應(yīng)的值,當(dāng)name不存在時(shí),則創(chuàng)建name=amount,否則,則自增。# name,Redis的name# amount,自增數(shù)(必須是整數(shù)) # 注:同incrbyincrbyfloat(self, name, amount=1.0) # 自增 name對(duì)應(yīng)的值,當(dāng)name不存在時(shí),則創(chuàng)建name=amount,否則,則自增。# name,Redis的name # amount,自增數(shù)(浮點(diǎn)型)decr(self, name, amount=1) # 自減 name對(duì)應(yīng)的值,當(dāng)name不存在時(shí),則創(chuàng)建name=amount,否則,則自減。# name,Redis的name# amount,自減數(shù)(整數(shù))append(key, value) # 在redis name對(duì)應(yīng)的值后面追加內(nèi)容# key, redis的name# value, 要追加的字符串3.2 Hash操作(字典操作)
redis中Hash在內(nèi)存中的存儲(chǔ)格式如下圖:
hset(name, key, value) # name對(duì)應(yīng)的hash中設(shè)置一個(gè)鍵值對(duì)(不存在,則創(chuàng)建;否則,修改)# name,redis的name# key,name對(duì)應(yīng)的hash中的key# value,name對(duì)應(yīng)的hash中的valuehsetnx(name, key, value) # 當(dāng)name對(duì)應(yīng)的hash中不存在當(dāng)前key時(shí)則創(chuàng)建(相當(dāng)于添加)hmset(name, mapping) # 在name對(duì)應(yīng)的hash中批量設(shè)置鍵值對(duì)# name,redis的name# mapping,字典,如:{'k1':'v1', 'k2': 'v2'} # 如:r.hmset('xx', {'k1':'v1', 'k2': 'v2'})hget(name,key) # 在name對(duì)應(yīng)的hash中獲取根據(jù)key獲取valuehmget(name, keys, *args) # 在name對(duì)應(yīng)的hash中獲取多個(gè)key的值# name,reids對(duì)應(yīng)的name# keys,要獲取key集合,如:['k1', 'k2', 'k3']# *args,要獲取的key,如:k1,k2,k3 # 如:r.mget('xx', ['k1', 'k2']) # 或:r.hmget('xx', 'k1', 'k2')hgetall(name) # 獲取name對(duì)應(yīng)hash的所有鍵值hlen(name) # 獲取name對(duì)應(yīng)的hash中鍵值對(duì)的個(gè)數(shù)hkeys(name) # 獲取name對(duì)應(yīng)的hash中所有的key的值hvals(name) # 獲取name對(duì)應(yīng)的hash中所有的value的值hexists(name, key) # 檢查name對(duì)應(yīng)的hash是否存在當(dāng)前傳入的keyhdel(name,*keys) # 將name對(duì)應(yīng)的hash中指定key的鍵值對(duì)刪除hincrby(name, key, amount=1) # 自增name對(duì)應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amount# name,redis中的name# key, hash對(duì)應(yīng)的key# amount,自增數(shù)(整數(shù))hincrbyfloat(name, key, amount=1.0) # 自增name對(duì)應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amount# name,redis中的name# key, hash對(duì)應(yīng)的key# amount,自增數(shù)(浮點(diǎn)數(shù)) # 自增name對(duì)應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amounthscan(name, cursor=0, match=None, count=None) # 增量式迭代獲取,對(duì)于數(shù)據(jù)大的數(shù)據(jù)非常有用,hscan可以實(shí)現(xiàn)分片的獲取數(shù)據(jù),并非一次性將數(shù)據(jù)全部獲取完,從而放置內(nèi)存被撐爆# name,redis的name# cursor,游標(biāo)(基于游標(biāo)分批取獲取數(shù)據(jù))# match,匹配指定key,默認(rèn)None 表示所有的key# count,每次分片最少獲取個(gè)數(shù),默認(rèn)None表示采用Redis的默認(rèn)分片個(gè)數(shù) # 如: # 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None) # 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None) # ... # 直到返回值cursor的值為0時(shí),表示數(shù)據(jù)已經(jīng)通過(guò)分片獲取完畢hscan_iter(name, match=None, count=None) # 利用yield封裝hscan創(chuàng)建生成器,實(shí)現(xiàn)分批去redis中獲取數(shù)據(jù)# match,匹配指定key,默認(rèn)None 表示所有的key# count,每次分片最少獲取個(gè)數(shù),默認(rèn)None表示采用Redis的默認(rèn)分片個(gè)數(shù) # 如: # for item in r.hscan_iter('xx'): # print item3.3 List操作
Redis中的List在在內(nèi)存中按照一個(gè)name對(duì)應(yīng)一個(gè)List來(lái)存儲(chǔ)。如圖:
lpush(name,values) # 在name對(duì)應(yīng)的list中添加元素,每個(gè)新的元素都添加到列表的最左邊 # 如:r.lpush('oo', 11,22,33) # 保存順序?yàn)? 33,22,11rpush(name, values) # 表示從右向左操作lpushx(name,value) # 在name對(duì)應(yīng)的list中添加元素,只有name已經(jīng)存在時(shí),值添加到列表的最左邊rpushx(name, value) # 在name對(duì)應(yīng)的list中添加元素,只有name已經(jīng)存在時(shí),值添加到列表的最右邊llen(name) # name對(duì)應(yīng)的list元素的個(gè)數(shù)linsert(name, where, refvalue, value)) # 在name對(duì)應(yīng)的列表的某一個(gè)值前或后插入一個(gè)新值# name,redis的name# where,BEFORE或AFTER# refvalue,標(biāo)桿值,即:在它前后插入數(shù)據(jù)# value,要插入的數(shù)據(jù)lset(name, index, value) # 對(duì)name對(duì)應(yīng)的list中的某一個(gè)索引位置重新賦值# name,redis的name# index,list的索引位置# value,要設(shè)置的值lrem(name, value, num) # 在name對(duì)應(yīng)的list中刪除指定的值# name,redis的name# value,要?jiǎng)h除的值# num, num=0,刪除列表中所有的指定值;# num=2,從前到后,刪除2個(gè);# num=-2,從后向前,刪除2個(gè)lpop(name) # 在name對(duì)應(yīng)的列表的左側(cè)獲取第一個(gè)元素并在列表中移除,返回值則是第一個(gè)元素rpop(name) # 在name對(duì)應(yīng)的列表的右側(cè)獲取第一個(gè)元素并在列表中移除,返回值則是第一個(gè)元素lindex(name, index) 在name對(duì)應(yīng)的列表中根據(jù)索引獲取列表元素lrange(name, start, end) # 在name對(duì)應(yīng)的列表分片獲取數(shù)據(jù)# name,redis的name# start,索引的起始位置# end,索引結(jié)束位置ltrim(name, start, end) # 在name對(duì)應(yīng)的列表中移除沒(méi)有在start-end索引之間的值# name,redis的name# start,索引的起始位置# end,索引結(jié)束位置rpoplpush(src, dst) # 從一個(gè)列表取出最右邊的元素,同時(shí)將其添加至另一個(gè)列表的最左邊# src,要取數(shù)據(jù)的列表的name# dst,要添加數(shù)據(jù)的列表的nameblpop(keys, timeout) # 將多個(gè)列表排列,按照從左到右去pop對(duì)應(yīng)列表的元素# keys,redis的name的集合# timeout,超時(shí)時(shí)間,當(dāng)元素所有列表的元素獲取完之后,阻塞等待列表內(nèi)有數(shù)據(jù)的時(shí)間(秒), 0 表示永遠(yuǎn)阻塞brpop(keys, timeout) # 將多個(gè)列表排列,按照從右向左去pop對(duì)應(yīng)列表的元素brpoplpush(src, dst, timeout=0) # 從一個(gè)列表的右側(cè)移除一個(gè)元素并將其添加到另一個(gè)列表的左側(cè)# src,取出并要移除元素的列表對(duì)應(yīng)的name# dst,要插入元素的列表對(duì)應(yīng)的name# timeout,當(dāng)src對(duì)應(yīng)的列表中沒(méi)有數(shù)據(jù)時(shí),阻塞等待其有數(shù)據(jù)的超時(shí)時(shí)間(秒),0 表示永遠(yuǎn)阻塞自定義增量迭代 # 由于redis類(lèi)庫(kù)中沒(méi)有提供對(duì)列表元素的增量迭代,如果想要循環(huán)name對(duì)應(yīng)的列表的所有元素,那么就需要: # 1、獲取name對(duì)應(yīng)的所有列表 # 2、循環(huán)列表 # 但是,如果列表非常大,那么就有可能在第一步時(shí)就將程序的內(nèi)容撐爆,所有有必要自定義一個(gè)增量迭代的功能:r = Redis.redis() def list_iter(name):"""自定義redis列表增量迭代:param name: redis中的name,即:迭代name對(duì)應(yīng)的列表:return: yield 返回 列表元素"""list_count = r.llen(name)for index in range(list_count):yield r.lindex(name, index)# 使用 for item in list_iter('pp'):print item3.4 Set操作
Set集合就是不允許重復(fù)的列表
sadd(name,values) # name對(duì)應(yīng)的集合中添加元素scard(name) # 獲取name對(duì)應(yīng)的集合中元素個(gè)數(shù)sdiff(keys, *args) # 在第一個(gè)name對(duì)應(yīng)的集合中且不在其他name對(duì)應(yīng)的集合的元素集合sdiffstore(dest, keys, *args) # 獲取第一個(gè)name對(duì)應(yīng)的集合中且不在其他name對(duì)應(yīng)的集合,再將其新加入到dest對(duì)應(yīng)的集合中sinter(keys, *args) # 獲取多一個(gè)name對(duì)應(yīng)集合的并集sinterstore(dest, keys, *args) # 獲取多一個(gè)name對(duì)應(yīng)集合的并集,再講其加入到dest對(duì)應(yīng)的集合中sismember(name, value) # 檢查value是否是name對(duì)應(yīng)的集合的成員smembers(name) # 獲取name對(duì)應(yīng)的集合的所有成員smove(src, dst, value) # 將某個(gè)成員從一個(gè)集合中移動(dòng)到另外一個(gè)集合spop(name) # 從集合的右側(cè)(尾部)移除一個(gè)成員,并將其返回srandmember(name, numbers) # 從name對(duì)應(yīng)的集合中隨機(jī)獲取 numbers 個(gè)元素srem(name, values) # 在name對(duì)應(yīng)的集合中刪除某些值sunion(keys, *args) # 獲取多一個(gè)name對(duì)應(yīng)的集合的并集sunionstore(dest,keys, *args) # 獲取多一個(gè)name對(duì)應(yīng)的集合的并集,并將結(jié)果保存到dest對(duì)應(yīng)的集合中sscan(name, cursor=0, match=None, count=None) sscan_iter(name, match=None, count=None) # 同字符串的操作,用于增量迭代分批獲取元素,避免內(nèi)存消耗太大3.5 有序集合
在集合的基礎(chǔ)上,為每元素排序;元素的排序需要根據(jù)另外一個(gè)值來(lái)進(jìn)行比較,所以,對(duì)于有序集合,每一個(gè)元素有兩個(gè)值,即:值和分?jǐn)?shù),分?jǐn)?shù)專門(mén)用來(lái)做排序。
zadd(name, *args, **kwargs) # 在name對(duì)應(yīng)的有序集合中添加元素 # 如:zadd('zz', 'n1', 1, 'n2', 2) # 或:zadd('zz', n1=11, n2=22)zcard(name) # 獲取name對(duì)應(yīng)的有序集合元素的數(shù)量zcount(name, min, max) # 獲取name對(duì)應(yīng)的有序集合中分?jǐn)?shù) 在 [min,max] 之間的個(gè)數(shù)zincrby(name, value, amount) # 自增name對(duì)應(yīng)的有序集合的 name 對(duì)應(yīng)的分?jǐn)?shù)r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float) # 按照索引范圍獲取name對(duì)應(yīng)的有序集合的元素# name,redis的name# start,有序集合索引起始位置(非分?jǐn)?shù))# end,有序集合索引結(jié)束位置(非分?jǐn)?shù))# desc,排序規(guī)則,默認(rèn)按照分?jǐn)?shù)從小到大排序# withscores,是否獲取元素的分?jǐn)?shù),默認(rèn)只獲取元素的值# score_cast_func,對(duì)分?jǐn)?shù)進(jìn)行數(shù)據(jù)轉(zhuǎn)換的函數(shù)# 更多: # 從大到小排序 # zrevrange(name, start, end, withscores=False, score_cast_func=float)# 按照分?jǐn)?shù)范圍獲取name對(duì)應(yīng)的有序集合的元素 # zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float) # 從大到小排序 # zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)zrank(name, value) # 獲取某個(gè)值在 name對(duì)應(yīng)的有序集合中的排行(從 0 開(kāi)始)# 更多: # zrevrank(name, value),從大到小排序zrangebylex(name, min, max, start=None, num=None) # 當(dāng)有序集合的所有成員都具有相同的分值時(shí),有序集合的元素會(huì)根據(jù)成員的 值 (lexicographical ordering)來(lái)進(jìn)行排序,而這個(gè)命令則可以返回給定的有序集合鍵 key 中, 元素的值介于 min 和 max 之間的成員 # 對(duì)集合中的每個(gè)成員進(jìn)行逐個(gè)字節(jié)的對(duì)比(byte-by-byte compare), 并按照從低到高的順序, 返回排序后的集合成員。 如果兩個(gè)字符串有一部分內(nèi)容是相同的話, 那么命令會(huì)認(rèn)為較長(zhǎng)的字符串比較短的字符串要大 # 參數(shù): # name,redis的name # min,左區(qū)間(值)。 + 表示正無(wú)限; – 表示負(fù)無(wú)限; ( 表示開(kāi)區(qū)間; [ 則表示閉區(qū)間 # min,右區(qū)間(值) # start,對(duì)結(jié)果進(jìn)行分片處理,索引位置 # num,對(duì)結(jié)果進(jìn)行分片處理,索引后面的num個(gè)元素 # 如: # ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga # r.zrangebylex(‘myzset’, “-“, “[ca”) 結(jié)果為:[‘a(chǎn)a’, ‘ba’, ‘ca’] # 更多: # 從大到小排序 # zrevrangebylex(name, max, min, start=None, num=None)zrem(name, values) # 刪除name對(duì)應(yīng)的有序集合中值是values的成員 # 如:zrem('zz', ['s1', 's2'])zremrangebyrank(name, min, max) # 根據(jù)排行范圍刪除zremrangebyscore(name, min, max) # 根據(jù)分?jǐn)?shù)范圍刪除zremrangebylex(name, min, max) # 根據(jù)值返回刪除zscore(name, value) # 獲取name對(duì)應(yīng)有序集合中 value 對(duì)應(yīng)的分?jǐn)?shù)zinterstore(dest, keys, aggregate=None) # 獲取兩個(gè)有序集合的交集,如果遇到相同值不同分?jǐn)?shù),則按照aggregate進(jìn)行操作 # aggregate的值為: SUM MIN MAXzunionstore(dest, keys, aggregate=None) # 獲取兩個(gè)有序集合的并集,如果遇到相同值不同分?jǐn)?shù),則按照aggregate進(jìn)行操作 # aggregate的值為: SUM MIN MAX zscan(name, cursor=0, match=None, count=None, score_cast_func=float) zscan_iter(name, match=None, count=None,score_cast_func=float) # 同字符串相似,相較于字符串新增score_cast_func,用來(lái)對(duì)分?jǐn)?shù)進(jìn)行操作3.6 其他常用操作
delete(*names) # 根據(jù)刪除redis中的任意數(shù)據(jù)類(lèi)型exists(name) # 檢測(cè)redis的name是否存在keys(pattern=’*’) # 根據(jù)模型獲取redis的name # 更多: # KEYS * 匹配數(shù)據(jù)庫(kù)中所有 key 。 # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 # KEYS h*llo 匹配 hllo 和 heeeeello 等。 # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hilloexpire(name ,time) # 為某個(gè)redis的某個(gè)name設(shè)置超時(shí)時(shí)間rename(src, dst) # 對(duì)redis的name重命名為move(name, db)) # 將redis的某個(gè)值移動(dòng)到指定的db下randomkey() # 隨機(jī)獲取一個(gè)redis的name(不刪除)type(name) # 獲取name對(duì)應(yīng)值的類(lèi)型scan(cursor=0, match=None, count=None) scan_iter(match=None, count=None) # 同字符串操作,用于增量迭代獲取keyttl(name) # 當(dāng) key 不存在時(shí),返回 -2 。當(dāng) key 存在但沒(méi)有設(shè)置剩余生存時(shí)間時(shí),返回 -1。否則以秒為單位,返回 key 的剩余生存時(shí)間。 # 注意:在 Redis 2.8 以前,當(dāng) key 不存在,或者 key 沒(méi)有設(shè)置剩余生存時(shí)間時(shí),命令都返回 -1 。四、管道
redis-py默認(rèn)在執(zhí)行每次請(qǐng)求都會(huì)創(chuàng)建(連接池申請(qǐng)連接)和斷開(kāi)(歸還連接池)一次連接操作,如果想要在一次請(qǐng)求中指定多個(gè)命令,則可以使用pipline實(shí)現(xiàn)一次請(qǐng)求指定多個(gè)命令,并且默認(rèn)情況下一次pipline 是原子性操作。
#!/usr/bin/env python # -*- coding:utf-8 -*-import redispool = redis.ConnectionPool(host='10.211.55.4', port=6379) r = redis.Redis(connection_pool=pool)# pipe = r.pipeline(transaction=False) pipe = r.pipeline(transaction=True) pipe.multi() # multi命令用于開(kāi)啟一個(gè)事務(wù),它總是返回ok,multi執(zhí)行之后, 客戶端可以繼續(xù)向服務(wù)器發(fā)送任意多條命令, 這些命令不會(huì)立即被執(zhí)行, 而是被放到一個(gè)隊(duì)列中, 當(dāng) EXEC 命令被調(diào)用時(shí), 所有隊(duì)列中的命令才會(huì)被執(zhí)行 pipe.set('name', 'alex') pipe.set('role', 'sb')pipe.execute() # 提交或者?
#!/usr/bin/env python # -*- coding:utf-8 -*- import redisconn = redis.Redis(host='192.168.1.41',port=6379) conn.set('count',1000)with conn.pipeline() as pipe:conn.watch('count') # 先監(jiān)視自己的值沒(méi)有被修改過(guò)。Watch 命令用于監(jiān)視一個(gè)(或多個(gè)) key ,如果在事務(wù)執(zhí)行之前這個(gè)(或這些) key 被其他命令所改動(dòng),那么事務(wù)將被打斷pipe.multi() # 事務(wù)開(kāi)始o(jì)ld_count = conn.get('count')count = int(old_count)if count > 0: # 有庫(kù)存pipe.set('count', count - 1)pipe.execute() # 執(zhí)行,把所有命令一次性推送過(guò)去五、發(fā)布訂閱
發(fā)布者:服務(wù)器
訂閱者:Dashboad和數(shù)據(jù)處理
Demo如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- import redisclass RedisHelper:def __init__(self):self.__conn = redis.Redis(host='10.211.55.4')self.chan_sub = 'fm104.5'self.chan_pub = 'fm104.5'def public(self, msg):self.__conn.publish(self.chan_pub, msg) # 頻道發(fā)布信息return Truedef subscribe(self):pub = self.__conn.pubsub()pub.subscribe(self.chan_sub) # 訂閱頻道 SUBSCRIBE fm104.5pub.parse_response()return pub訂閱者:
#!/usr/bin/env python # -*- coding:utf-8 -*- from?monitor.RedisHelper?import?RedisHelperobj?=?RedisHelper() redis_sub?=?obj.subscribe()while?True:msg=?redis_sub.parse_response()print?msg發(fā)布者:
#!/usr/bin/env python # -*- coding:utf-8 -*-from?monitor.RedisHelper?import?RedisHelperobj?=?RedisHelper() obj.public('hello')六、sentinel(哨兵)
Redis重的sentinel主要用于在redis主從復(fù)制中,如果master顧上,則自動(dòng)將slave替換成master
#!/usr/bin/env python # -*- coding:utf-8 -*-from?redis.sentinel?import?Sentinel# 連接哨兵服務(wù)器(主機(jī)名也可以用域名) sentinel?=?Sentinel([('10.211.55.20',?26379),('10.211.55.20',?26380),], socket_timeout=0.5)# 獲取主服務(wù)器地址 master = sentinel.discover_master('mymaster') print(master)# 獲取從服務(wù)器地址 slave = sentinel.discover_slaves('mymaster') print(slave)# 獲取主服務(wù)器進(jìn)行寫(xiě)入 master = sentinel.master_for('mymaster') master.set('foo', 'bar')# 獲取從服務(wù)器進(jìn)行讀取(默認(rèn)是round-roubin) slave = sentinel.slave_for('mymaster', password='redis_auth_pass') r_ret = slave.get('foo') print(r_ret)更多參見(jiàn):https://github.com/andymccurdy/redis-py/
http://doc.redisfans.com/
總結(jié)
以上是生活随笔為你收集整理的Redis Python的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Django REST framewor
- 下一篇: Python 第三方模块之 pdfkit