天天看點

Python—redis

一、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

1、連接配接方式

  redis-py提供兩個類Redis和StrictRedis用于實作Redis的指令,StrictRedis用于實作大部分官方的指令,并使用官方的文法和指令,Redis是StrictRedis的子類

複制代碼

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import redis

r = redis.Redis(host='192.168.0.110', port=6379,db=0)

r.set('name', 'zhangsan')   #添加

print (r.get('name'))   #擷取

2、連接配接池

  redis-py使用connection pool來管理對一個redis server的所有連接配接,避免每次建立、釋放連接配接的開銷。預設,每個Redis執行個體都會維護一個自己的連接配接池。

可以直接建立一個連接配接池,然後作為參數Redis,這樣就可以實作多個Redis執行個體共享一個連接配接池。

pool = redis.ConnectionPool(host='192.168.0.110', port=6379)

r = redis.Redis(connection_pool=pool)

3、操作

 redis詳細操作指令 

4、管道

  redis-py預設在執行每次請求都會建立(連接配接池申請連接配接)和斷開(歸還連接配接池)一次連接配接操作,

如果想要在一次請求中指定多個指令,則可以使用pipline實作一次請求指定多個指令,并且預設情況下

一次pipline 是原子性操作。

pipe = r.pipeline(transaction=True)

r.set('name', 'zhangsan')

r.set('name', 'lisi')

pipe.execute()

5、釋出和訂閱

首先定義一個RedisHelper類,連接配接Redis,定義頻道為monitor,定義釋出(publish)及訂閱(subscribe)方法。

#-*- coding:utf-8 -*-

class 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

#釋出

from RedisHelper import RedisHelper

obj = RedisHelper()

obj.publish('hello')#釋出

redis_sub = obj.subscribe()#調用訂閱方法

while True:

    msg= redis_sub.parse_response()

    print (msg)

1、String 操作

  redis中的String在在記憶體中按照一個name對應一個value來存儲

set()

#在Redis中設定值,預設不存在則建立,存在則修改

'''參數:

     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")) #輸出:zhangsan

print(r.get("name1")) #輸出:wangwu

getrange(key, start, end)

#根據位元組擷取子序列

r.set("name","zhangsan")

print(r.getrange("name",0,3))#輸出:zhan

setrange(name, offset, value)

#修改字元串内容,從指定字元串索引開始向後替換,如果新值太長時,則向後添加

r.setrange("name",1,"z")

print(r.get("name")) #輸出:zzangsan

r.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對應的變成了0b110001

print(r.get("name"))#輸出:145

getbit(name, offset)

#擷取name對應值的二進制中某位的值(0或1)

r.set("name","3") # 對應的二進制0b110011

print(r.getbit("name",5))   #輸出:0

print(r.getbit("name",6))   #輸出:1

bitcount(key, start=None, end=None)

#擷取對應二進制中1的個數

r.set("name","345")#0b110011 0b110100 0b110101

print(r.bitcount("name",start=0,end=1)) #輸出:7

''' key:Redis的name

    start:位元組起始位置

    end:位元組結束位置'''

strlen(name)

#傳回name對應值的位元組長度(一個漢字3個位元組)

print(r.strlen("name")) #輸出:8

incr(self, name, amount=1)

#自增mount對應的值,當mount不存在時,則建立mount=amount,否則,則自增,amount為自增數(整數)

print(r.incr("mount",amount=2))#輸出:2

print(r.incr("mount"))#輸出:3

print(r.incr("mount",amount=3))#輸出:6

print(r.incr("mount",amount=6))#輸出:12

print(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對應的值後面追加内容

print(r.get("name"))    #輸出:'zhangsan

r.append("name","lisi")

print(r.get("name"))    #輸出:zhangsanlisi

2、Hash 操作

redis中的Hash 在記憶體中類似于一個name對應一個dic來存儲 

 hset(name, key, value)

#name對應的hash中設定一個鍵值對(不存在,則建立,否則,修改)

r.hset("dic_name","a1","aa")

hget(name,key)

#在name對應的hash中根據key擷取value

print(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)

#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是否存在目前傳入的key

print(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、List 操作

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)

    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,将多個清單排列,按照從右像左去移除各個清單内的元素

4、Set 操作

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_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對應集合的并集

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對應的集合中

有序集合:

  在集合的基礎上,為每元素排序,元素的排序需要根據另外一個值來進行比較,是以,對于有序集合,每一個元素有兩個值,即:值和分數,分數專門用來做排序。

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_name1', a1=7,b1=10, b2=5)

# 擷取兩個有序集合的交集并放入dest集合,如果遇到相同值不同分數,則按照aggregate進行操作

# aggregate的值為: SUM  MIN  MAX

r.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對應值的類型

本文轉自 chengxuyonghu 51CTO部落格,原文連結:http://blog.51cto.com/6226001001/1853937,如需轉載請自行聯系原作者