python-redis

1.Redis是什么?

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如
    字符串(strings),
    散列(hashes),
    列表(lists),
    集合(sets),
    有序集合(sorted sets)
    与范围查询, bitmaps, hyperloglogs
    和 地理空间(geospatial) 索引半径查询。

2.Centos上安装redis

设置Redis的仓库地址
        yum install epel-release

        安装redis
        yum install redis

        更改监听地址。
        vim   /etc/redis.conf
        找到:bind 127.0.0.1
        更改:bind 0.0.0.0
         #   0.0.0.0 是监听所有的请求

        #并且设置了连接密码认证。
        找到:requirepass foobared
        更改:requirepass  这里填写你的密码



        启动redis,到此完成
        service redis start

        如果需要设置开机自动启动
        chkconfig redis on

        redis 配置详细说明:http://www.redis.net.cn/tutorial/3504.html

3.python 安装 redis 模块

pip3 install redis

4.python 使用 redis

  

基本包括:

    String 操作
    Hash 操作
    List 操作
    Set 操作

4.1 连接redis 方式

redis 服务器上设置了连接密码认证。password

1.普通连接方式
    rd = redis.Redis(host='127.0.0.1',port=6379,password='yourpassword')

2. 连接池方式
  pool = redis.ConnectionPool(host='127.0.0.1',port=6379,password='yourpassword')
  rd = redis.Redis(connection_pool=pool)

"""
    连接池方式。
    redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。
    默认,每个Redis实例都会维护一个自己的连接池。
    可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
"""

 4,2 python-redis String 操作

    String 操作
    文档:http://www.redis.cn/commands/get.html

4.2.1 get(name)

"""
    get(name)
    返回key的value。如果key不存在,返回特殊值nil。如果key的value不是string,就返回错误,
    因为GET只处理string类型的values。
"""
rd.set('name','py-redis-pool')
print(rd.get('name'))

4.2.2 set(name, value, ex=None, px=None, nx=False, xx=False)

"""
    set(name, value, ex=None, px=None, nx=False, xx=False)
    在Redis中设置值,默认,不存在则创建,存在则修改
    参数:
    从2.6.12版本开始,redis为SET命令增加了一系列选项:
    
    EX seconds – 设置键key的过期时间,单位时秒
    PX milliseconds – 设置键key的过期时间,单位时毫秒
    NX – 只有键key不存在的时候才会设置key的值
    XX – 只有键key存在的时候才会设置key的值
    注意: 由于SET命令加上选项已经可以完全取代SETNX, SETEX, PSETEX的功能,
    所以在将来的版本中,redis可能会不推荐使用并且最终抛弃这几个命令。
"""

rd.set('py-ex','1314',ex=2)
print(rd.get('py-ex'))

rd.set('py-px','1314',px=10)
print(rd.get('py-px'))

rd.set('py-nx','1314',nx=True)
print(rd.get('py-px'))

rd.set('py-xx','1314',xx=True)
print(rd.get('py-xx'))

4.2.3 mset({key:value,key:value,...})

"""
批量设置值
mset({key:value,key:value,...})
    对应给定的keys到他们相应的values上。MSET会用新的value替换已经存在的value,就像普通的SET命令一样。
    MSET是原子的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
    ##返回值 总是OK,因为MSET不会失败。
"""
rd.mset({'mset_name1':'mset_1','mset_name2':'mset_2'})
print(rd.mget(['mset_name1','mset_name2']))

4.2.4 getset(name,value)

"""
获取原来的值并设置新的值
getset(name,value)
    自动将key对应到value并且返回原来key对应的value。
    如果key存在但是对应的value不是字符串,就返回错误。
    
    ##返回值 返回之前的旧值,如果之前Key不存在将返回nil。
"""
print(rd.getset('defer','async1'))

4.2.5 getrange(key,start,end)

"""
截取对应key值的符合长度的字符串
getrange(key,start,end)
这个命令是被改成GETRANGE的,在小于2.0的Redis版本中叫SUBSTR。

## 返回值,存在字符串,不存在空
"""

rd.set('getrange_key','getrange_value')

print(rd.getrange('getrange_key',0,2))
print(rd.getrange('getrange_key',-5,-1))
print(rd.getrange('getrange_key',0,-1))
print(rd.getrange('getrange_key',30,100))

4.2.6 setrange(name,offset,value)

"""
覆盖从offset开始的字符串
setrange(name,offset,value)
"""rd.set('setrange_key','setrange_value')

rd.setrange('setrange_key',3,'RAN')
print(rd.get('setrange_key'))

4.2.7 setbit(key,offset,value)

"""
将value转换成二进制
然后对offset,设置0或者1.
setbit(key,offset,value)

##返回值
"""
# 例子:
def strTobin(strs):
    strbinlists = []
    strlen = 0
    for s in strs:
        strbinlists.append(format(ord(s),'b'))
    return strbinlists

def binTostr(binlists):
    retstr=''
    for strbin in binlists:
        retstr += chr(int(strbin,2))
    return retstr

strbinlists = strTobin('setbit_value')
print(strbinlists)
strbinlists[0] = '1110010' # 将第七位改为0
print(binTostr(strbinlists))

rd.set('setbit_key','setbit_value')
rd.setbit('setbit_key',7,0)
print(rd.get('setbit_key'))

 4.2.8 bitcount(key,start,end)

"""
统计值转换成二进制之后,其中有多少位1
bitcount(key,start,end)
统计字符串被设置为1的bit数.
一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。
start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。
不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。
"""
rd.set('bitcount_key','value')
print(rd.bitcount('bitcount_key'))
"""
额外的思路。
假如一个系统有两亿多的活动用户。需要你统计在线用户数量,还能查看某个用户在不在线。

思路:可以使用redis setbin,getbin,bincount来实现。

例如:用户一旦上线,设置
    setbit user_pool 1234 1     (1234 是用户的自增id)
那么:
    统计在线用户:bitcount() 
    查看某个用户在不在线,getbit user_pool 1234
    
优点就是以位数存储用户信息占用的空间非常之少。
"""

4.2.9 incr(key,amount)

"""
自增
incr(key,amount)
对存储在指定key的数值执行原子的加1操作。
"""
rd.set('user_login',0)
rd.incr('user_login',2)
rd.incr('user_login')
rd.incr('user_login')
print(rd.get('user_login'))

4.2.10 decr(key,amount)

"""
自减
decr(key,amount)
对key对应的数字做减1操作。如果key不存在,那么在操作之前,这个key对应的值会被置为0。
如果key有一个错误类型的value或者是一个不能表示成数字的字符串,就返回错误。
这个操作最大支持在64位有符号的整型数字。
"""

rd.set('user_login',3)
rd.decr('user_login')
rd.decr('user_login')
rd.decr('user_login')
rd.decr('user_login')
print(rd.get('user_login'))

4.2.11 append(key,value)

"""
追加字符串
append(key,value)
如果 key 已经存在,并且值为字符串,那么这个命令会把 value 追加到原来值(value)的结尾。 
如果 key 不存在,那么它将首先创建一个空字符串的key,再执行追加操作
## 返回append后字符串值(value)的长度。
"""
rd.set('append_key','append_value')
rd.append('append_key','new')
print(rd.get('append_key'))

4.3  Hash 操作

官方文档:http://www.redis.cn/commands/hdel.html

4.3.1 hset(name,key,value)  hget(name,key)  hget(name,key)  hgetall(name)  hkeys(name)  hvals(name)

"""
hset(name,key,value)
hget(name,key)
hgetall(name) # 获取属于name的所有的键值
hkeys(name) #获取属于name的所有的键
hvals(name) #获取属于name的所有的值
"""
rd.hset('h1','name','cat')
rd.hset('h1','age','3')
rd.hset('h2','name','dog')
rd.hset('h2','age','2')
rd.hset('h3','name','bee')
rd.hset('h3','age','2')
#
print(rd.hgetall('h1'))
print(rd.hget('h2','age'))
print(rd.hkeys('h2'))
print(rd.hvals('h3'))

4.3.2 批量操作

"""
批量
hmset(name,mapping={})
hmget(name,key)
hexists(name,key) 判断是否存在。
hdel(name,key) 删除
hincrby(name,key,amount=1)自增
hincrbyfloat(name,key,amount=1)
"""
rd.hmset(name='m1',mapping={'name':'dog','age':3,'count':1})

print(rd.hmget('m1','name'))

rd.hdel('m1','age')

print(rd.hexists('m1','age'))
rd.hincrby('m1','count',1)
print(rd.hget('m1','count'))

4.3.3 匹配过滤

"""
匹配过滤
hscan(name,cursor match,count)

hscan_iter(name,cursor match,count) t同上,不过是返回一个迭代器。
"""

rd.hset('k1','name','dog')
rd.hset('k1','name2','cat')
rd.hset('k1','name3','bee')
rd.hset('k1','none','none')
print(rd.hscan('k1',0,'no*'))

print(rd.hscan_iter(rd.hscan('k1',0,'n*')))

4.4  list 列表操作  http://www.redis.cn/commands/lpush.html

4.4.1 lpush(name,value:Tuple[Any,...])    从左,添加一个列表 (注意是添加,不会覆盖)

rd.lpush('animal','cat')
print(rd.lrange('animal',0,-1))

4.4.2 rpush(name,value:Tuple[Any,...]) 从右,添加一个列表 (注意是添加,不会覆盖)

rd.rpush('animal','dog')
print(rd.lrange('animal',0,-1))

4.4.3 linsert(name: Any, where: Any, refvalue: Any, value: Any) 

"""
linsert(name: Any, where: Any, refvalue: Any, value: Any)
    把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
    当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。
    当 key 存在,但保存的不是一个list的时候,会返回error。

"""
rd.linsert('animal','before','cat','bee')
#
print(rd.lrange('animal',0,-1))

4.4.4  其他

"""
    lset(name,index,value)
        设置 index 位置的list元素的值为 value。
        当index超出范围时会返回一个error。
    lrem(name,value,num)
        从存于 key 的列表里移除前 num 次出现的值为 value 的元素。
            num > 0: 从头往尾移除值为 value 的元素。
            num < 0: 从尾往头移除值为 value 的元素。
            num = 0: 移除所有值为 value 的元素。
    lpop(name)
        移除并且返回 key 对应的 list 的第一个元素。
        
    lindex(name,index)
        返回列表里的元素的索引 index 存储在 key 里面。
        
    ltrim(name,start,end)
        修剪(trim)一个已存在的 list,这样 list 就会只包含指定范围的指定元素。
        start 和 stop 都是由0开始计数的, 
        这里的 0 是列表里的第一个元素(表头),1 是第二个元素
        
    rpoplpush(source,destination)
        原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素),
        并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)。 

    blpop(keys,timeout)
        如果keys存在,则立刻删除,如果keys不存在,则等待timeout秒。
        如果给定 key 内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,
        并和被弹出元素所属的列表的名字 key 一起,组成结果返回给调用者。
        当存在多个给定 key 时, BLPOP 按给定 key 参数排列的先后顺序,依次检查各个列表。 
        我们假设 key list1 不存在,而 list2 和 list3 都是非空列表。
    
    brpoplpush(source,destination,timeout)
    BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本。 
    当 source 包含元素的时候,这个命令表现得跟 RPOPLPUSH 一模一样。 
    当 source 是空的时候,Redis将会阻塞这个连接,直到另一个客户端 push 元素进入或者达到 timeout 时限。
    timeout 为 0 能用于无限期阻塞客户端。
"""

print(rd.lrange('animal',0,-1))

rd.lset('animal',1,'BEE')
print(rd.lrange('animal',0,-1))
rd.lrem('animal','dog',1)
print(rd.lrange('animal',0,-1))

print(rd.lindex('animal',1))

rd.ltrim('animal',0,1)
print(rd.lrange('animal',0,-1))
rd.blpop()

4.5 set 集合操作

import redis
pool = redis.ConnectionPool(host='127.0.0.1',port=6379,password='.....')
rd = redis.Redis(connection_pool=pool)

"""
sadd(name,values,...)
    添加一个或多个指定的values元素到集合的 name中.
    指定的一个或者多个元素values 如果已经在集合name中存在则忽略.
    如果集合name 不存在,则新建集合name,并添加member元素到集合name中.

smembers(name)
    返回name集合所有的元素.

scard(name)
    返回集合元素的数量
    
sdiff(name,name)
    返回一个集合与给定集合的差集.
    
sdiffstore(destination,name,name..)
    和sdiff类似,不过该命令不返回结果集,而是将结果存放在destination集合中.
    如果destination已经存在, 则将其覆盖重写

sinter(name,name)
    返回指定所有的集合的成员的交集.
sinterstore(destination,name,name..)
    和sinter类似,不过该命令不返回结果集,而是将结果存放在destination集合中.
    如果destination已经存在, 则将其覆盖重写
    
sismember(name,value)
    返回value是否存在name中,Ture or False
    
smove(source,destination,value)
    将source的value转移到destination中。

srandmember(name,member)
    随机返回集合中的元素,member指定返回个数
    
srem(name,value)
    移除集合指定的value
    
sunion(name,name...)
    返回给定的多个集合的并集中的所有成员.
sunionstore(destination,name,name..)
    和sunion类似,不过该命令不返回结果集,而是将结果存放在destination集合中.
    如果destination已经存在, 则将其覆盖重写
"""
rd.sadd('sname','dd','ddd','as')
rd.sadd('sname2','dd','ddd')
print(rd.smembers('sname'))
print(rd.scard('sname'))

print(rd.sdiff('sname','sname2'))
print(rd.sinter('sname','sname2'))

print(rd.sismember('sname','dd'))

rd.smove('sname','sname2','aa')
print(rd.srem('sname',"['ya', 'xa', 'wa', 'qa']"))
print(rd.smembers('sname'))
print(rd.smembers('sname2'))
print(rd.srandmember('sname',2))

print(rd.sunion('sname','sname2'))



"""
    http://www.redis.cn/commands/zadd.html
    redis 有序集合的操作
    
    zadd(name,value,num,value2,num2,...)  或者
    zadd(name,value=num,value2=num2,...)
        添加有序集合
        如果>= Redis 3.0.2
        ZADD 命令在key后面分数/成员(score/member)对前面支持一些参数,他们是:
        XX: 仅仅更新存在的成员,不添加新成员。
        NX: 不更新存在的成员。只添加新成员。
        CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
        INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
    
    zcard(name)
        返回有序集合的元素个数
        
    zcount(name,min,max)
        返回有序集合,序号在min和max之间的个数
        
    zrange(name,value,amount)
        自增有序集合的序号
    
"""

rd.zadd('zname','qa',1,'xa',2,'dd',5)
rd.zadd('zname',qa=1,xa=2,cc=3)
print(rd.zrange('zname',0,-1))
print(rd.zcard('zname'))
#
print(rd.zcount('zname',3,8))
#
rd.zincrby('zname','cc',2)
#
print(rd.zrange('zname',0,-1,withscores=True))


"""
    其他常用操作
    delete(name)
        删除name
    exists(name)
        是否存在
    expire(name,time)
        为某个name指定超时时间
        
    move(name,db)
        移动name到指定db
        redis 中 存在16个db,select dbnum 切换打包
        
    randomkey()
        随机获取一个redis的name
        
    type(name)
        查看类型
"""

其他类型参考官方中文文档 http://www.redis.cn/commands/

猜你喜欢

转载自www.cnblogs.com/yzhl/p/python-redis.html