redis-py是一套使用Python编程语言访问Redis服务器的接口库。
1. 安装redis-py
1 2 3 4 5 6 7 8 |
# 1. 使用pip安装 $ sudo pip install redis # 2. 使用easy_install安装 $ sudo easy_install redis # 3. 从源码安装 $ sudo python setup.py install |
2. 简单的使用示例
1 2 3 4 5 6 |
>>> import redis >>> r = redis.StrictRedis(host='localhost', port=6379, db=0) >>> r.set('foo', 'bar') True >>> r.get('foo') 'bar' |
3. 连接Redis服务器
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,其中StrictRedis实现了绝大部分Redis官方提供的接口,Redis继承自StrictRedis,提供对之前较老版本的接口的兼容支持。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import redis # 1. 直接连接 r = redis.StrictRedis(host='localhost', port=6379, db=0) r.set('foo', 'bar') print(r.get('foo')) # 2. 使用连接池(可实现多个实例之间共享连接池) pool = redis.ConnectionPool(host='127.0.0.1', port=6379) r1 = redis.StrictRedis(connection_pool=pool) r2 = redis.StrictRedis(connection_pool=pool) r1.set('foo', 'bar') r2.set('foo', 'bbaarr') print(r1.get('foo'), r2.get('foo'), sep='\n') |
4. 解析返回值
当执行完redis接口命令后,返回的结果为字节数组形式,需要将其解析为实际的数据结构。redis-py默认使用PythonParser进行解析,如果安装了HiredisParser,将使用HiredisParser进行解析,其执行速度是PythonParser的十倍左右。
1 |
$ pip install hiredis |
在StrictRedis类中,使用RESPONSE_CALLBACKS字典存储所有将命令返回值解析为Python数据类型的回调函数信息,用户自定义的命令与其回调函数可以通过StrictRedis的实例的 set_response_callback() 函数加入到该字典,但作用域仅限于该实例。
5. 使用Pipeline
Pipeline是Redis的子类,实现了缓存多个redis命令,使其能够在一次请求中完成,从而显著提高批量redis命令处理的效率。
1 2 3 4 5 6 7 8 9 10 |
>>> r = redis.StrictRedis(host='localhost', port=6379, db=0) >>> r.set('bing', 'baz') >>> # 1. 调用pipeline()函数创建pipeline实例 >>> pipe = r.pipeline() >>> # 2. 缓存多个redis命令 >>> pipe.set('foo', 'bar') >>> pipe.get('bing') >>> # execute()函数将缓存的命令发送到redis服务器依次执行,并返回一个执行结果列表,每个命令一个值 >>> pipe.execute() [True, 'baz'] |
默认情况下Pipeline缓存的命令将作为一组命令执行,具有事务特性和原子性,执行时要么全部执行,要么全部都不执行。若要禁用事务特性,可以在创建时指定参数 pipe = r.pipeline(transaction=False) 。
6. 发布/订阅
Redis中的发布/订阅机制是一种消息通信模式,由发布者在指定频道上发布消息,所有订阅了该频道的订阅者都将收到该消息。简单示例如下:
1 2 3 4 |
import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) r.publish('my_channel', 'test message') r.publish('my_channel', 'xxx') |
1 2 3 4 5 6 7 8 |
import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) pubsub= r.pubsub() pubsub.subscribe('my_channel') pubsub.parse_response() while True: msg= pubsub.parse_response() print (msg) |
7. 常用的接口操作
7.1 string接口操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
''' set语法 set(name, value, ex=None, px=None, nx=False, xx=False) ex,过期时间(秒) px,过期时间(毫秒) nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value) xx,如果设置为True,则只有name存在时,当前set操作才执行 ''' import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) r.set('name', 'zhangsan') r.set('name', 'zhangsan', ex=30) r.set('name', 'zhangsan', px= 5000, xx=True) # setrange(name, offset, value)使用value从offset位置开始替换name对应的值 r.setrange("name",1,"zz") # "name" => b'zzzngsan' r.setrange("name",1,"xxxxxxxx") # "name" => b'zxxxxxxxx' # 批量设置值 r.mset(name1='zhangsan', name2='lisi') r.mset({"name1":'zhangsan', "name2":'lisi'}) # 设置新值,打印原值 r.getset("name1","wangwu") # b'zhangsan' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) r.set('key_name', 'Hello, Redis') r.mset(name1='zhangsan', name2='lisi') # 获取键key_name对应的值 r.get('key_name') # b'Hello, Redis' # 获取键key_name对应的值中索引在[1, 4]范围内的字符串 r.getrange('key_name', 1, 4) # b'ello' # 批量获取指定键的值 r.mget("name1","name2") # [b'zhangsan', b'lisi'] r.mget(["name1","name2"]) # [b'zhangsan', b'lisi'] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) r.set('key_name', 'Hello, Redis') r.set('mount', 10) # 返回key_name对应值的字节长度 r.strlen("key_name") # 12 # 向key_name对应值末尾追加内容 r.append('key_name', '123aaa') # b'Hello, Redis123aaa' # 对key_name对应值进行自增/自减计算 r.incr('mount') # 11 r.incr('mount', amount=3) # 14 r.decr('mount') # 13 r.decr('mount', amount=3) # 10 r.incrbyfloat('mount') # 11.0 r.incrbyfloat('mount', amount=1.27) # 12.27 r.incrbyfloat('mount', amount=-1.27)# 11.0 |
7.2 Hash接口操作
Redis中的hash结构是由一个key,若干个字段和字段对应的值构成,特别适合存储对象数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) # 设置指定key指定field对应的value r.hset('key1', 'field1', 'value1') # 批量设置 r.hmset('key2',{'field2': 'value2', 'field22':'value22'}) # 获取指定key指定field对应的value r.hget('key1', 'field1') # b'value1' # 获取指定key对应的所有field键值对 r.hgetall('key1') # {b'field1': b'value1'} r.hgetall('key2') # {b'field2': b'value2', b'field22': b'value22'} # 批量获取 r.hmget('key2', ['field2', 'field22']) # 获取key中field键值对个数 r.hlen('key2') # 2 # 获取key对应的所有field键值对中键列表 r.hkeys('key2') # [b'field2', b'field22'] # 获取key对应的所有field键值对中的值列表 r.hvals('key2') # [b'value2', b'value22'] # 设置指定key指定field的值的自增计算 r.hset('key3', 'num', 10) r.hincrby('key3', 'num') # 11 r.hincrby('key3', 'num', amount= 3) # 14 r.hincrbyfloat('key3', 'num') # 15.0 r.hincrbyfloat('key3', 'num', amount=-3.0) # 12.0 # 检查指定key指定field对应的键值对是否存在 r.hexists('key3', 'num') # True r.hexists('key3', 'num2') # False # 删除指定key指定field对应的键值对 r.hdel('key3', 'num') |
7.3 list接口操作
Redis中的List是按照一个键对应一个列表的方式存储的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) # 从左侧向key1对应的列表中添加元素序列 r.lpush('key1', 2) # key1 => [2] r.lpush('key1', 3, 4, 5) # key1 => [5,4,3,2] # 从右侧向key2对应的列表中添加元素序列 r.rpush('key2', 2) # key2 => [2] r.rpush('key2', 3, 4, 5) # key2 => [2, 3, 4, 5] # 当且仅当key存在时,从左侧/右侧向key对应的列表添加元素序列 r.lpushx('key1', 6) # key1 => [6, 5,4,3,2] r.rpushx('key2', 6) # key2 => [2, 3, 4, 5, 6] # 向列表中指定位置插入数据 ''' linsert语法说明 linsert(name, where, refvalue, value)) name: redis的name where: BEFORE(前)或AFTER(后) refvalue: 列表内的值 value: 要插入的数据''' r.linsert("key3","BEFORE","ref_value","insert_value") # 设置列表指定位置的值 r.lset('key2', 3, '555') # 获取列表指定位置的值 r.lindex('key2', 3) # b'555' # 获取key对应的列表中指定范围的元素列表 r.lrange('key2', 1, 4) # [b'3', b'4', b'555'] # 移除key对应的列表中指定区域之外的所有元素 r.ltrim('key2', 1, 4) # key2 => [b'3', b'4', b'555'] # rpoplpush(src, dst),从src列表的右侧取出一个元素,将其添加到dst列表的左侧 r.rpoplpush('key2', 'key1') # [b'555', b'6', b'5', b'4', b'3', b'2'] # 计算key对应的列表中元素个数 r.llen('key2') # 3 # 删除key对应列表中指定元素 ''' lrem语法 lrem(name, count, value) name: redis中的key count: count=0 删除列表中所有的指定值; count=2 从前到后,删除2个; count=-2 从后向前,删除2个 value: 要删除的值''' r.lrem('key2', 0, 4) # key2 => [b'2', b'3'] # 移除key对应列表左侧/右侧第一个元素,并返回其值 r.lpop('key2') # 返回值:b'2', key2 => [b'3'] r.rpop('key1') # 返回值:b'2', key1 => [b'555', b'6', b'5', b'4', b'3'] |
7.4 Set接口操作
Redis中Set集合元素不能重复,一个key对应着一个集合对象,集合对象里包含若干不重复的集合元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) # 添加集合元素 r.sadd('key1', 'value1') r.sadd('key1', 'value12', 'value13') # 获取集合中全部元素 r.smembers('key1') # {b'value1', b'value12', b'value13'} # 获取集合中元素个数 r.scard('key1') # 3 r.sadd('key2', 'value12') r.sadd('key3', 'value13') # 计算key对应的集合元素与输入的其它集合之间的并集 r.sunion('key1', 'key2') # {b'value1', b'value12', b'value13'} r.sunion('key1', 'key2', 'key3') # {b'value1', b'value12', b'value13'} # 计算key对应的集合元素与输入的其它集合之间的并集,并将结果存储到新的集合中 r.sunion('key5', 'key1', 'key2') # key5 => {b'value1', b'value12', b'value13'} # 计算key对应的集合元素与输入的其它集合之间的差集 r.sdiff('key1', 'key2') # {b'value1', b'value13'} r.sdiff('key1', 'key2', 'key3') # {b'value1'} # 计算key对应的集合元素与输入的其它集合之间的差集,并将结果存储到新的集合中 sdiffstore('key4', 'key1', 'key2') # key4 => {b'value1', b'value13'} # 计算key对应的集合元素与其它集合之间的交集 r.sinter('key1', 'key2') # {b'value12'} r.sinter('key1', 'key2', 'key3') # {} # 计算key对应的集合元素与其它集合之间的交集,并将结果存储到新的集合中 r.sinter('key6', 'key1', 'key2') # key6 => {b'value12'} # 检查指定值是否为key所对应集合中的元素 r.sismember('key1', 'value1') # True # 将元素从一个集合移动到另一个集合 r.smove('key1', 'key2', 'value1') # key2 => {b'value1', b'value12'} # 删除集合中的某些值 r.srem('key1', 'value12', 'value13') # key1 => {} |
7.5 有序集合zset的操作接口
有序集合将元素拆分为元素值和权重两部分,以便使用权重对元素进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) # 添加集合元素 r.zadd('key1', 3, 'value1', 5, 'value12', 4, 'value13') r.zadd('key2', value1=3, value12=5, value13=4) # key1 => [b'value1', b'value13', b'value12'] # 计算集合中元素个数 r.zcard('key1') # 3 # 计算集合内权重在指定范围内的元素个数 r.zcount('key1',1, 4) # 2 # 将键为key1,值为value1的权重进行自增计算 r.zincrby('key1', 'value1') # 4.0 r.zincrby('key1', 'value1', amount= -3) # 1.0 # 按照已排序集合的索引范围获取key对应有序集合中的指定子集 ''' 语法说明 zrange( name, start, end, desc=False, withscores=False, score_cast_func=float) name redis的name start 有序集合索引起始位置 end 有序集合索引结束位置 desc 排序规则,默认按照分数从小到大排序 withscores 是否获取元素的分数,默认只获取元素的值 score_cast_func 对权重进行数据转换的函数''' r.zrange('key1', 0, 1) # [b'value1', b'value13'] r.zrange('key1', 0, 1, desc= True) # [b'value12', b'value13'] r.zrange('key1', 0, 1, desc= True, withscores= True) # [(b'value12', 5.0), (b'value13', 4.0)] # 获取指定key指定值的排序 r.zrank('key1', 'value1') # 0 r.zrevrank('key1', 'value1') # 2 # 获取指定key指定值的权重 r.zscore('key1', 'value1') # 1.0 # 删除key对应的集合中的指定元素值 r.zrem('key1', 'value1') # key1 => [b'value13', b'value12'] r.zrem('key1', 'value12', 'value13')# key1 => [] # 根据排序,删除权重在指定范围内的元素 r.zremrangebyscore('key2', 4.0, 6.0) # 根据排序,删除排序在指定范围内的元素 r.zremrangebyrank('key2', 0, 1) # 获取指定的多个集合的交集,并使用指定算法合并权重,最后将结果存放到新的集合中 r.zinterstore('key3', ('key1', 'key2'), aggregate="MAX") # 获取指定的多个集合的并集,并使用指定算法合并权重,最后将结果存放到新的集合中 r.zunionstore('key4', ('key1', 'key2'), aggregate="SUM") |
7.6 其它常用操作函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import redis r= redis.StrictRedis(host='localhost', port=6379, db=0) # 删除指定的一个或一组key对应的数据 r.delete('key1') r.delete('key2', 'key3') # 检查key是否存在 r.exist('key4') # 使用通配符匹配redis中的key r.keys(pattern= '*') # 为某个key设置超时时间 r.expire('key5', 30) # 重命名指定key r.rename('key6', 'new_key_name') # 将指定key移动到指定的db中 r.move('key7', 3) # 获取key对应的数据类型 r.type('key8') |