標籤:gre agg 調用 並集 主從同步 mapping highlight mat member
一、redis簡介
redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value類型相對更多,包括string(字串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(雜湊類型)。這些資料類型都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是緩衝在記憶體中。區別的是redis會周期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。
Redis 是一個高效能的key-value資料庫。 redis的出現,很大程度補償了memcached這類key/value儲存的不足,在部 分場合可以對關聯式資料庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP用戶端,使用很方便,Redis支援主從同步。資料可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹複製。從盤可以有意無意的對資料進行寫操作。由於完全實現了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的訊息發布記錄。
二、python連結redis方式2.1普通連結方式
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的文法和命令,Redis是StrictRedis的子類
#!/usr/bin/env python# -*- coding:utf-8 -*-import redisr = redis.Redis(host=‘192.168.0.110‘, port=6379,db=0)r.set(‘name‘, ‘zhangsan‘) #添加print (r.get(‘name‘)) #擷取
2.2連結池
redis-py使用connection pool來管理對一個redis server的所有串連,避免每次建立、釋放串連的開銷。預設,每個Redis執行個體都會維護一個自己的串連池。可以直接建立一個串連池,然後作為參數Redis,這樣就可以實現多個Redis執行個體共用一個串連池。
#!/usr/bin/env python# -*- coding:utf-8 -*-import redispool = redis.ConnectionPool(host=‘192.168.0.110‘, port=6379)r = redis.Redis(connection_pool=pool)r.set(‘name‘, ‘zhangsan‘) #添加print (r.get(‘name‘)) #擷取
2.3管道
redis-py預設在執行每次請求都會建立(串連池申請串連)和斷開(歸還串連池)一次串連操作,如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且預設情況下一次pipline 是原子性操作。
#!/usr/bin/env python# -*- coding:utf-8 -*-import redispool = redis.ConnectionPool(host=‘192.168.0.110‘, port=6379)r = redis.Redis(connection_pool=pool)pipe = r.pipeline(transaction=True)r.set(‘name‘, ‘zhangsan‘)r.set(‘name‘, ‘lisi‘)pipe.execute()
2.4發布和訂閱
首先定義一個RedisHelper類,串連Redis,定義頻道為monitor,定義發布(publish)及訂閱(subscribe)方法。
#!/usr/bin/env python#-*- coding:utf-8 -*-import redisclass RedisHelper(object): def __init__(self): self.__conn = redis.Redis(host=‘192.168.0.110‘,port=6379)#串連Redis self.channel = ‘monitor‘ #定義名稱 def publish(self,msg):#定義發布方法 self.__conn.publish(self.channel,msg) return True def subscribe(self):#定義訂閱者法 pub = self.__conn.pubsub() pub.subscribe(self.channel) pub.parse_response() return pub
發行者
#!/usr/bin/env python# -*- coding:utf-8 -*-#發布from RedisHelper import RedisHelperobj = RedisHelper()obj.publish(‘hello‘)#發布
訂閱者
#!/usr/bin/env python# -*- coding:utf-8 -*-#訂閱from RedisHelper import RedisHelperobj = RedisHelper()redis_sub = obj.subscribe()#調用訂閱者法while True: msg= redis_sub.parse_response() print (msg)
三、python-redis模組操作命令
redis支援五大資料類型: string、Hash(python中字典,字典嵌套時,被嵌套字典為字串)、list、set(集合)、有序集合
3.1String 操作
redis中的String在在記憶體中按照一個name對應一個value來儲存
set()
#在Redis中設定值,預設不存在則建立,存在則修改r.set(‘name‘, ‘zhangsan‘)‘‘‘參數: set(name, value, ex=None, px=None, nx=False, xx=False) ex,到期時間(秒) px,到期時間(毫秒) nx,如果設定為True,則只有name不存在時,當前set操作才執行,同setnx(name, value) xx,如果設定為True,則只有name存在時,當前set操作才執行‘‘‘setex(name, value, time)#設定到期時間(秒)psetex(name, time_ms, value)#設定到期時間(豪秒)
mset()
#大量設定值r.mset(name1=‘zhangsan‘, name2=‘lisi‘)#或r.mget({"name1":‘zhangsan‘, "name2":‘lisi‘})
get(name)
擷取值
mget(keys, *args)
#批量擷取print(r.mget("name1","name2"))#或li=["name1","name2"]print(r.mget(li))
getset(name, value)
#設定新值,列印原值print(r.getset("name1","wangwu")) #輸出:zhangsanprint(r.get("name1")) #輸出:wangwu
getrange(key, start, end)
#根據位元組擷取子序列r.set("name","zhangsan")print(r.getrange("name",0,3))#輸出:zhan
setrange(name, offset, value)
#修改字串內容,從指定字串索引開始向後替換,如果新值太長時,則向後添加r.set("name","zhangsan")r.setrange("name",1,"z")print(r.get("name")) #輸出:zzangsanr.setrange("name",6,"zzzzzzz")print(r.get("name")) #輸出:zzangszzzzzzz
setbit(name, offset, value)
#對二進位表示位進行操作‘‘‘ name:redis的name offset,位的索引(將值對應的ASCII碼變換成二進位後再進行索引) value,值只能是 1 或 0 ‘‘‘str="345"r.set("name",str)for i in str: print(i,ord(i),bin(ord(i)))#輸出 值、ASCII碼中對應的值、對應值轉換的二進位‘‘‘輸出: 3 51 0b110011 4 52 0b110100 5 53 0b110101‘‘‘r.setbit("name",6,0)#把第7位改為0,也就是3對應的變成了0b110001print(r.get("name"))#輸出:145
getbit(name, offset)
#擷取name對應值的二進位中某位的值(0或1)r.set("name","3") # 對應的二進位0b110011print(r.getbit("name",5)) #輸出:0print(r.getbit("name",6)) #輸出:1
bitcount(key, start=None, end=None)
#擷取對應二進位中1的個數r.set("name","345")#0b110011 0b110100 0b110101print(r.bitcount("name",start=0,end=1)) #輸出:7‘‘‘ key:Redis的name start:位元組起始位置 end:位元組結束位置‘‘‘
strlen(name)
#返回name對應值的位元組長度(一個漢字3個位元組)r.set("name","zhangsan")print(r.strlen("name")) #輸出:8
incr(self, name, amount=1)
#自增mount對應的值,當mount不存在時,則建立mount=amount,否則,則自增,amount為自增數(整數)print(r.incr("mount",amount=2))#輸出:2print(r.incr("mount"))#輸出:3print(r.incr("mount",amount=3))#輸出:6print(r.incr("mount",amount=6))#輸出:12print(r.get("mount")) #輸出:12
incrbyfloat(self, name, amount=1.0)
#類似 incr() 自增,amount為自增數(浮點數)
decr(self, name, amount=1)
#自減name對應的值,當name不存在時,則建立name=amount,否則,則自減,amount為自增數(整數)
append(name, value)
#在name對應的值後面追加內容r.set("name","zhangsan")print(r.get("name")) #輸出:‘zhangsanr.append("name","lisi")print(r.get("name")) #輸出:zhangsanlisi
3.2Hash 操作
redis中的Hash 在記憶體中類似於一個name對應一個dic來儲存
hset(name, key, value)
#name對應的hash中設定一個索引值對(不存在,則建立,否則,修改)r.hset("dic_name","a1","aa")
hget(name,key)
r.hset("dic_name","a1","aa")#在name對應的hash中根據key擷取valueprint(r.hget("dic_name","a1"))#輸出:aa
hgetall(name)
#擷取name對應hash的所有索引值print(r.hgetall("dic_name"))
hmset(name, mapping)
#在name對應的hash中大量設定索引值對,mapping:字典dic={"a1":"aa","b1":"bb"}r.hmset("dic_name",dic)print(r.hget("dic_name","b1"))#輸出:bb
hmget(name, keys, *args)
# 在name對應的hash中擷取多個key的值li=["a1","b1"]print(r.hmget("dic_name",li))print(r.hmget("dic_name","a1","b1"))
hlen(name)、hkeys(name)、hvals(name)
dic={"a1":"aa","b1":"bb"}r.hmset("dic_name",dic)#hlen(name) 擷取hash中索引值對的個數print(r.hlen("dic_name"))#hkeys(name) 擷取hash中所有的key的值print(r.hkeys("dic_name"))#hvals(name) 擷取hash中所有的value的值print(r.hvals("dic_name"))
hexists(name, key)
#檢查name對應的hash是否存在當前傳入的keyprint(r.hexists("dic_name","a1"))#輸出:True
hdel(name,*keys)
#刪除指定name對應的key所在的索引值對r.hdel("dic_name","a1")
hincrby(name, key, amount=1)
#自增hash中key對應的值,不存在則建立key=amount(amount為整數)print(r.hincrby("demo","a",amount=2))
hincrbyfloat(name, key, amount=1.0)
#自增hash中key對應的值,不存在則建立key=amount(amount為浮點數)
hscan(name, cursor=0, match=None, count=None)
hscan_iter(name, match=None, count=None)
3.3List操作
redis中的List在在記憶體中按照一個name對應一個List來儲存
lpush(name,values)
# 在name對應的list中添加元素,每個新的元素都添加到列表的最左邊r.lpush("list_name",2)r.lpush("list_name",3,4,5)#儲存在列表中的順序為5,4,3,2
rpush(name,values)
#同lpush,但每個新的元素都添加到列表的最右邊
lpushx(name,value)
#在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊
rpushx(name,value)
#在name對應的list中添加元素,只有name已經存在時,值添加到列表的最右邊
llen(name)
# name對應的list元素的個數print(r.llen("list_name"))
linsert(name, where, refvalue, value))
# 在name對應的列表的某一個值前或後插入一個新值r.linsert("list_name","BEFORE","2","SS")#在列表內找到第一個元素2,在它前面插入SS‘‘‘參數: name: redis的name where: BEFORE(前)或AFTER(後) refvalue: 列表內的值 value: 要插入的資料‘‘‘
r.lset(name, index, value)
#對list中的某一個索引位置重新賦值r.lset("list_name",0,"bbb")
r.lrem(name, value, num)
#刪除name對應的list中的指定值r.lrem("list_name","SS",num=0)‘‘‘ 參數: name: redis的name value: 要刪除的值 num: num=0 刪除列表中所有的指定值; num=2 從前到後,刪除2個; num=-2 從後向前,刪除2個‘‘‘
lpop(name)
#移除列表的左側第一個元素,傳回值則是第一個元素print(r.lpop("list_name"))
lindex(name, index)
#根據索引擷取列表內元素print(r.lindex("list_name",1))
lrange(name, start, end)
#分區擷取元素print(r.lrange("list_name",0,-1))
ltrim(name, start, end)
#移除列表內沒有在該索引之內的值r.ltrim("list_name",0,2)
rpoplpush(src, dst)
# 從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊#src 要取資料的列表#dst 要添加資料的列表
brpoplpush(src, dst, timeout=0)
#同rpoplpush,多了個timeout, timeout:取資料的列表沒元素後的阻塞時間,0為一直阻塞r.brpoplpush("list_name","list_name1",timeout=0)
blpop(keys, timeout)
#將多個列表排列,按照從左至右去移除各個列表內的元素r.lpush("list_name",3,4,5)r.lpush("list_name1",3,4,5)while True: print(r.blpop(["list_name","list_name1"],timeout=0)) print(r.lrange("list_name",0,-1),r.lrange("list_name1",0,-1))‘‘‘keys: redis的name的集合 timeout: 逾時時間,擷取完所有列表的元素之後,阻塞等待列表內有資料的時間(秒), 0 表示永遠阻塞‘‘‘
r.brpop(keys, timeout)
#同blpop,將多個列表排列,按照從右像左去移除各個列表內的元素
3.4Set 操作
Set集合就是不允許重複的列表
sadd(name,values)
#給name對應的集合中添加元素r.sadd("set_name","aa")r.sadd("set_name","aa","bb")
smembers(name)
#擷取name對應的集合的所有成員
scard(name)
#擷取name對應的集合中的元素個數r.scard("set_name")
sdiff(keys, *args)
#在第一個name對應的集合中且不在其他name對應的集合的元素集合r.sadd("set_name","aa","bb")r.sadd("set_name1","bb","cc")r.sadd("set_name2","bb","cc","dd")print(r.sdiff("set_name","set_name1","set_name2"))#輸出:{aa}
sdiffstore(dest, keys, *args)
#相當於把sdiff擷取的值加入到dest對應的集合中
sinter(keys, *args)
# 擷取多個name對應集合的並集r.sadd("set_name","aa","bb")r.sadd("set_name1","bb","cc")r.sadd("set_name2","bb","cc","dd")print(r.sinter("set_name","set_name1","set_name2"))#輸出:{bb}
sinterstore(dest, keys, *args)
#擷取多個name對應集合的並集,再講其加入到dest對應的集合中
sismember(name, value)
#檢查value是否是name對應的集合內的元素
smove(src, dst, value)
#將某個元素從一個集合中移動到另外一個集合
spop(name)
#從集合的右側移除一個元素,並將其返回
srandmember(name, numbers)
# 從name對應的集合中隨機擷取numbers個元素print(r.srandmember("set_name2",2))
srem(name, values)
#刪除name對應的集合中的某些值print(r.srem("set_name2","bb","dd"))
sunion(keys, *args)
#擷取多個name對應的集合的並集r.sunion("set_name","set_name1","set_name2")
sunionstore(dest,keys, *args)
#擷取多個name對應的集合的並集,並將結果儲存到dest對應的集合中
3.5有序集合
在集合的基礎上,為每元素排序,元素的排序需要根據另外一個值來進行比較,所以,對於有序集合,每一個元素有兩個值,即:值和分數,分數專門用來做排序。
zadd(name, *args, **kwargs)
# 在name對應的有序集合中添加元素r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5)#或r.zadd(‘zset_name1‘, b1=10, b2=5)
zcard(name)
#擷取有序集合內元素的數量
zcount(name, min, max)
#擷取有序集合中分數在[min,max]之間的個數print(r.zcount("zset_name",1,5))
zincrby(name, value, amount)
#自增有序集合內value對應的分數r.zincrby("zset_name","a1",amount=2)#自增zset_name對應的有序集合裡a1對應的分數
zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
# 按照索引範圍擷取name對應的有序集合的元素aa=r.zrange("zset_name",0,1,desc=False,withscores=True,score_cast_func=int)print(aa)‘‘‘參數: name redis的name start 有序集合索引起始位置 end 有序集合索引結束位置 desc 定序,預設按照分數從小到大排序 withscores 是否擷取元素的分數,預設只擷取元素的值 score_cast_func 對分數進行資料轉換的函數‘‘‘
zrevrange(name, start, end, withscores=False, score_cast_func=float)
#同zrange,集合是從大到小排序的
zrank(name, value)、zrevrank(name, value)
#擷取value值在name對應的有序集合中的排行位置(從0開始)print(r.zrank("zset_name", "a2"))print(r.zrevrank("zset_name", "a2"))#從大到小排序
zscore(name, value)
#擷取name對應有序集合中 value 對應的分數print(r.zscore("zset_name","a1"))
zrem(name, values)
#刪除name對應的有序集合中值是values的成員r.zrem("zset_name","a1","a2")
zremrangebyrank(name, min, max)
#根據排行範圍刪除
zremrangebyscore(name, min, max)
#根據分數範圍刪除
zinterstore(dest, keys, aggregate=None)
r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5)r.zadd(‘zset_name1‘, a1=7,b1=10, b2=5)# 擷取兩個有序集合的交集並放入dest集合,如果遇到相同值不同分數,則按照aggregate進行操作# aggregate的值為: SUM MIN MAXr.zinterstore("zset_name2",("zset_name1","zset_name"),aggregate="MAX")print(r.zscan("zset_name2"))
zunionstore(dest, keys, aggregate=None)
#擷取兩個有序集合的並集並放入dest集合,其他同zinterstore,
其他常用操作
delete(*names)
#根據name刪除redis中的任意資料類型
exists(name)
#檢測redis的name是否存在
keys(pattern=‘*‘)
#根據* ?等萬用字元匹配擷取redis的name
expire(name ,time)
# 為某個name設定逾時時間
rename(src, dst)
# 重新命名
move(name, db))
# 將redis的某個值移動到指定的db下
randomkey()
#隨機擷取一個redis的name(不刪除)
type(name)
# 擷取name對應值的類型
python之redis模組