Redis
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis模块安装:sudo pip install redis
#!/usr/bin/env python #coding:utf8 import redis pool=redis.ConnectionPool(host='127.0.0.1',port=6379) r=redis.Redis(connection_pool=pool) r.set('name','xym')#设置key,value print r.keys()#获取所有key print r.get('name')#通过key获取value r.set('sex',18,nx=True)#nx=True sex不存在才执行,否则设置了也不生效 r.set('sex',19,nx=True)#sex的值还是18 print r.get('sex') r.set('id',1,ex=5)#ex=5 5秒钟过期 r.set('id',5,xx=True)#id必须已经存在,设置才生效 r.setnx('files','1.txt')#files不存在,才生效 r.setex('name','xym',3)#3秒过期 r.psetex('name',4000,'xym')#name,过期时间4000毫秒,value r.mset(k1='k1',k2='k2')#批量设置 print r.mget(['k1','k2'])#批量获取 print r.keys() r.set('k1','aaa') print r.getset('name','k1')#设置新值name=k1,获取旧的k1的值 print r.get('name') r.set('name','xuyanmei') print r.getrange('name',0,4)#获取0到4范围的key值 r.set('name','xuyanmei') r.setrange('name',0,'love')#从索引0开始把love替换 结果:lovenmei print r.strlen('name')# lovenmei 长度为8 .获取name值的长度 r.incr('nums',amount=1)#如果nums不存在,设置nums=1,多次设置值为自增 #nums=1 #nums=2 #nums=3 r.incrbyfloat('nums',amount=2.0)#如果nums不存在,nums的值每次自增2 r.decr('aa',amount=1)#如果nums存在,nums=19,每次自减1.否则nums=-1每次自减等于-2 r.append('name','kis')#name对应的值后面追加内容 #lovenmeikis r.hset('n1','age','20')#设置hash表中的键值 r.hmset('n2',{'a':1,'b2':2})#批量设置hash表中的键值 ############### get ################# print r.hget('n1','age')#获取hash表中n1的键值 print r.hmget('n1',['age'])#在name对应的hash中获取多个key的值 print r.hgetall('n2')#获取name对应hash的所有键值 print r.hlen('n2')#获取name对应的hash中键值对的个数 print r.hkeys('n2')#获取name对应的hash中所有的key的值 print r.hvals('n2')#获取name对应的hash中所有的value的值 print r.hexists('n2','a')#检查name对应的hash是否存在当前传入的key r.hdel('n2','a')#将name对应的hash中指定key的键值对删除 r.hincrby('n2','a')#自增name对应的hash中的指定key的值,不存在则创建key=amount r.hincrbyfloat('n2','c')#自增name对应的hash中的指定key的值,不存在则创建key=amount ####################list#################### r.lpush('name_list','a','b','c')#创建列表,从右往左的顺序操作 print r.lrange('name_list',0,-1)#查询列表指定范围 r.lpushx('name_list','e')## 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边,一次只能插入一个值 print r.llen('name_list')# name对应的list元素的个数 r.linsert('name_list','BEFORE','b',123)#在列表name_list,元素b的前面插入123 ['e', 'c', '123', 'b', 'a'] r.linsert('name_list','AFTER','c','love')#在列表name_list,元素c的前面插入love ['e', 'c', 'love', '123', 'b', 'a'] r.lset('name_list',2,'xuyanmei')#对name对应的list中的某一个索引位置重新赋值 ['e', 'c', 'xuyanmei', '123', 'b', 'a'] print r.lrange('name_list',0,-1) r.lrem('name_list','c',2) # value,要删除的值 # num, num=0,删除列表中所有的指定值; # num=2,从前到后,删除2个; # num=-2,从后向前,删除2个 data=r.blpop('name_list')#在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素 # print r.lrange('name_list',0,-1) #name 列表名字 # start,索引的起始位置 # end,索引结束位置 r.ltrim('name_list',3,6)#在name对应的列表中移除没有在start-end索引之间的值
集合
r.delete("s") r.delete('s2') print(r.sadd("s", "a", 'b')) # 添加数据到集合's' print(r.smembers('s')) # 查看集合成员 print(r.scard('s')) # 判定集合长度,不存在则为0 print(r.sismember('s', 'a')) # 判定对象是否存在集合里 print(r.sadd('s2', 'a')) print(r.sinter('s', 's2')) # 获取两个集合的交集,{b'a'} print(r.sinterstore('s3', 's', 's2')) # 求交集,并把结果付给s3,返回交集个数 print(r.smembers('s3')) print(r.smembers('s')) # {b'b', b'a'} print(r.smembers('s2')) # {b'a'} print(r.sunion('s', 's2')) # {b'b', b'a'}求并集,返回两个集合的所有元素,不重复 print(r.sunionstore('s4', 's', 's2')) # 将两个集合的并集赋值给s4 print(r.smembers('s4')) print(r.sdiff('s', 's2')) # 求集合s里有,但是集合s2里没有的元素 print(r.sdiffstore('s5', 's', 's2')) # 将两个集合的差集赋值给S5 print(r.smembers('s5')) print(r.srandmember('s')) # 取随机元素 print(r.smove(src='s', dst='s6', value='b')) # 将集合成员b移到另一个集合,成功为True,否则False print(r.smembers('s6')) print(r.smembers('s')) print(r.sadd('s', 11, 33, 44)) print(r.smembers('s')) print(r.spop('s')) # 移除尾部一个成员,并将其返回 print(r.srem('s', 11)) # 删除集合成员11 print(r.smembers('s'))
#print(r.sadd('s', 11, 22, 33, 11, 10)) #print(r.sscan(name='s', count=1, match="1*")) # 匹配集合1*的成员 #print(r.sscan_iter('s', match='1*')) # 返回一个迭代器,用于增量分批获取元素,避免内存消耗太大
有序集合
print(r.delete('zs')) print(r.zadd('zs', 'h1', 1, 'h2', 2)) print(r.zadd('zs', n1=11, n2=22)) print(r.zcard('zs')) # 获取集合长度,也就是成员个数 print(r.zcount('zs', 1, 23)) # 获取集合分数在1到23之间,包含1和23的个数 print(r.zincrby('zs', 11, amount=1)) # 自增集合对应成员的有序集合的对应分数 print(r.zincrby('zs', 11, amount=1)) print(r.zrange(name='zs', start=0, end=-1)) # 获取集合范围内的有序集合成员 # 参数: # name,redis的name # start,有序集合索引起始位置(非分数) # end,有序集合索引结束位置(非分数) # desc,排序规则,默认按照分数从小到大排序 # withscores,是否获取元素的分数,默认只获取元素的值 # score_cast_func,对分数进行数据转换的函数 print(r.zrevrange(name='zs', start=0, end=-1)) # 按照分数从大到小排序集合 print(r.zrangebyscore(name='zs', min=1, max=11)) # 获取集合分数内的成员 print(r.zrevrangebyscore(name='zs', max=13, min=1)) # 按照分数从大到小排序集合成员 print(r.zrank(name='zs', value='h2')) # 获取某个成员在集合中的排行 print(r.zrevrank(name='zs', value='n1')) # 从大到小排序,获取某个成员排行位置 print(r.zrem('zs', 'n1')) # 删除集合对应的成员 print(r.zrange('zs', 0, -1)) print(r.zremrangebyrank(name='zs', min=1, max=2)) # 删除指定排序范围成员,即删除下标1,不包含1,到下标2,包含2 print(r.zrange('zs', 0, -1))
print(r.zremrangebyscore(name='zs', min=1, max=20)) # 删除指定分数范围内的集合成员 print(r.zrange(name='zs', start=0, end=-1)) print(r.zscore(name='zs', value='n2')) # 返回集合成员对应的分数,浮点数 r.delete('s2') print(r.zadd('s2', n3=222, n2=222)) print(r.zinterstore(dest='news', keys=['zs', 's2'])) # 求两个有序集合的并集 print(r.zrange(name='news', start=0, end=-1)) print(r.zunionstore(dest='nn', keys=['zs', 's2'])) # 求两个集合的并集,如果遇到不同值分数,则按照aggregate进行操作 # aggregate值为:SUM,MIN,MAX print(r.zrange(name='nn', start=0, end=-1)) print(r.zscan(name='zs', count=1)) # 同字符串类似,新增score_cast_func用来进行对分数进行操作 print(r.delete('test')) # 删除任意数据类型 print(r.exists(name="test")) # 判断name是否存在 print(r.keys(pattern="*")) # 打印所有匹配对KEY # KEYS * 匹配数据库中所有 key 。 # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 # KEYS h*llo 匹配 hllo 和 heeeeello 等。 # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo print(r.expire(name='zs', time=2)) # 为某个name设置超时时间 print(r.rename(src='zs', dst='ns')) # 重命名某个name print(r.move(name='zs', db=2)) # 将某个name移到到指定DB下,前提name存在,否则返回False print(r.randomkey()) # 随机获取一个name,不删除 print(r.type("zs")) # 获取name对应对类型
管道
redis-py默认值执行每次请求都会创建连接池申请连接,和断开连接池一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下,一次pipline是原子性操作
import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) pipe = r.pipeline(transaction=True) r.set('name', 'xym') r.set('role', 'master') pipe.execute()
发布订阅
创建redis_common.py
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 """ 4 5 """ 6 import redis 7 8 9 class RedisHelper(object): 10 def __init__(self): 11 self.__conn = redis.Redis(host="127.0.0.1") 12 self.chan_pub = 'fm104.5' 13 self.chan_sub = 'fm104.5' 14 15 def public(self, msg): 16 self.__conn.publish(self.chan_pub, message=msg) 17 return True 18 19 def subscribe(self): 20 pub = self.__conn.pubsub() 21 pub.subscribe(self.chan_sub) 22 pub.parse_response() 23 return pub
创建发布者redis_pub.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 """ 4 5 """ 6 from redis_common import RedisHelper 7 8 obj = RedisHelper() 9 obj.public('hello') # 发布一条消息到频道fm104.5
创建订阅者redis_sub.py
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 """ 4 5 """ 6 from redis_common import RedisHelper 7 8 obj = RedisHelper() 9 redis_sub = obj.subscribe() 10 11 while True: 12 msg = redis_sub.parse_response() # 此时一直阻塞状态,直到能接收到数据, 13 print(msg)