之前有在windows上安装redis,现在我们就是用python实际操作下redis,并记录一些常用模块,方面后面翻阅查找资料
windows的安装方法笔记:https://sulao.cn/post/655.html
linux安装方法的笔记:https://sulao.cn/post/178.html
使用python操作redis,我们需要先安装redis模块
pip install redis
接下来我们看看python如何操作redis,python操作redis主要有两种方法
1.redis类来操作
#!/usr/bin/python3 #coding:utf-8 import redis r = redis.Redis(host="127.0.0.1",port=6379) nick_hash = r.get("nick") print(nick_hash.decode("utf-8"))
打印如下
2.使用连接池来操作redis
使用连接池来管理redis所有的连接,避免了每次建立连接和释放的开销,默认每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数 Redis,这样就可以实现多个Redis实例共享一个连接池,我们来看看实例
#!/usr/bin/python3 #coding:utf-8 import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) #r.set("name","shevechco") r1 = r.get("nick") print(r1.decode("utf-8"))
下面是一些常用操作方法详解
redis中的String操作
set(name, value, ex=None, px=None, nx=False, xx=False) 在Redis中设置值,默认,不存在则创建,存在则修改 参数: ex,过期时间(秒) px,过期时间(毫秒) nx,如果设置为True,则只有name不存在时,当前set操作才执行 xx,如果设置为True,则只有name存在时,岗前set操作才执行
我们来设置一个超时的时间测试下
#!/usr/bin/python3 #coding:utf-8 import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) #r.set("alias","yang.su", ex=5) print(r.get("alias").decode("utf-8"))
我们看到设置ex=5,然后5秒以后再去获取之前设置的key就报错了。
mset这个方法是用来批量设置key,value的,我们可以一次计行多个插入,参数我使用的字典,至于提示可以使用list,我没试出来,有报错
#!/usr/bin/python3 #coding:utf-8 import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) r.mset({"xing":"su", "ming":"yang"}) print(r.get("xing")) print(r.get("ming")) #打印 b'su' b'yang'
当然有批量设置也可以批量取出来的方法,这个方法就是mget,我们直接看例子
#!/usr/bin/python3 #coding:utf-8 import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) r.mset({"xing":"su", "ming":"yang"}) print(r.mget("xing","ming")) #打印 list类型 [b'su', b'yang']
getset(name, value)可以获取原来的值并同时获取新值
后面几个目前来说还用的太少,先记录以后再进行学习
getrange(key, start, end)获取子序列(根据字节获取,非字符) setrange(name, offset, value)修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加) setbit(name, offset, value)对name对应值的二进制表示的位进行操作 getbit(name, offset)获取name对应的值的二进制表示中的某位的值 (0或1) bitcount(key, start=None, end=None)获取name对应的值的二进制表示中 1 的个数 incr(self, name, amount=1)自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增 incrbyfloat(self, name, amount=1.0)自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增 decr(self, name, amount=1)自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减 append(key, value)在redis name对应的值后面追加内容
Redis中的hash操作,主要有以下方法,暂时不展开学习
hset(name, key, value)name对应的hash中设置一个键值对(不存在,则创建;否则,修改) hmset(name, mapping)在name对应的hash中批量设置键值对 hgetall(name)获取name对应hash的所有键值 hlen(name)获取name对应的hash中键值对的个数 hkeys(name)获取name对应的hash中所有的key的值 hvals(name)获取name对应的hash中所有的value的值 hexists(name, key)检查name对应的hash是否存在当前传入的key hdel(name,*keys)将name对应的hash中指定key的键值对删除 hincrby(name, key, amount=1)自增name对应的hash中的指定key的值,不存在则创建key=amount hincrbyfloat(name, key, amount=1.0)自增name对应的hash中的指定key的值,不存在则创建key=amount hscan(name, cursor=0, match=None, count=None)增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆 hscan_iter(name, match=None, count=None)利用yield封装hscan创建生成器,实现分批去redis中获取数据
Redis中list操作,redis中的List在在内存中按照一个name对应一个List来存储
lpush(name,values)在name对应的list中添加元素,每个新的元素都添加到列表的最左边 lpushx(name,value)在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边 llen(name)name对应的list元素的个数 linsert(name, where, refvalue, value))在name对应的列表的某一个值前或后插入一个新值 r.lset(name, index, value)对name对应的list中的某一个索引位置重新赋值 r.lrem(name, value, num)在name对应的list中删除指定的值 lpop(name)在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素 ltrim(name, start, end)在name对应的列表中移除没有在start-end索引之间的值 rpoplpush(src, dst)从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边 blpop(keys, timeout)将多个列表排列,按照从左到右去pop对应列表的元素 lindex(name, index)在name对应的列表中根据索引获取列表元素
Rdis中Set操作,Set集合就是不允许重复的列表
sadd(name,values)name对应的集合中添加元素 scard(name)获取name对应的集合中元素个数 sdiff(keys, *args)在第一个name对应的集合中且不在其他name对应的集合的元素集合 sdiffstore(dest, keys, *args)获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中 sinter(keys, *args)获取多一个name对应集合的并集 sinterstore(dest, keys, *args)获取多一个name对应集合的并集,再讲其加入到dest对应的集合中 sismember(name, value)检查value是否是name对应的集合的成员 smembers(name)获取name对应的集合的所有成员 smove(src, dst, value)将某个成员从一个集合中移动到另外一个集合 spop(name)从集合的右侧(尾部)移除一个成员,并将其返回 srandmember(name, numbers)从name对应的集合中随机获取 numbers 个元素 srem(name, values)在name对应的集合中删除某些值 sunion(keys, *args)获取多一个name对应的集合的并集 sunionstore(dest,keys, *args)获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中 有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。 zadd(name, *args, **kwargs)在name对应的有序集合中添加元素获取name对应的有序集合元素的数量 zcount(name, min, max)获取name对应的有序集合中分数 在 [min,max] 之间的个数 zincrby(name, value, amount) 自增name对应的有序集合的 name 对应的分数 r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)按照索引范围获取name对应的有序集合的元素 zrank(name, value)获取某个值在 name对应的有序集合中的排行(从 0 开始) zrangebylex(name, min, max, start=None, num=None)当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值 (lexicographical ordering)来进行排序,而这个命令则可以返回给定的有序集合键 key 中, 元素的值介于 min 和 max 之间的成员 zrem(name, values)删除name对应的有序集合中值是values的成员 zremrangebyrank(name, min, max)根据排行范围删除 zremrangebyscore(name, min, max)根据分数范围删除 zremrangebylex(name, min, max)根据值返回删除 zscore(name, value)获取name对应有序集合中 value 对应的分数 zinterstore(dest, keys, aggregate=None)获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作 zunionstore(dest, keys, aggregate=None)获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作 rename(src, dst)对redis的name重命名 move(name, db))将redis的某个值移动到指定的db下 randomkey()随机获取一个redis的name(不删除) type(name)获取name对应值的类型
python redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作
#!/usr/bin/python3 #coding:utf-8 import redis pool = redis.ConnectionPool(host="127.0.0.1", port=6379) r = redis.Redis(connection_pool=pool) p = r.pipeline(transaction=True) r.set("test1", "sulao") r.set("test2", "laosu") p.execute() print("获取缓存 test1:{}, test2:{}".format(r.get("test1"),r.get("test2")))
redis发布订阅
发布者:服务器
订阅者:Dashboad和数据处理
Demo如下:
#!/usr/bin/python3 #coding:utf-8 import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host='10.211.55.4') self.chan_sub = 'fm104.5' self.chan_pub = 'fm104.5' def public(self, msg): self.__conn.publish(self.chan_pub, msg) return True def subscribe(self): pub = self.__conn.pubsub() pub.subscribe(self.chan_sub) pub.parse_response() return pub
订阅者
#!/usr/bin/python3 #coding:utf-8 from monitor.RedisHelper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg= redis_sub.parse_response() print(msg)
发布者:
#!/usr/bin/python3 #coding:utf-8 from monitor.RedisHelper import RedisHelper obj = RedisHelper() obj.public('hello')
redis中的sentinel主要用于在redis主从复制中,如果master故障,则自动将slave替换成master
#!/usr/bin/python3 #coding:utf-8 from redis.sentinel import Sentinel # 连接哨兵服务器(主机名也可以用域名) sentinel = Sentinel([('10.211.55.20', 26379), ('10.211.55.20', 26380), ], socket_timeout=0.5) # 获取主服务器地址 master = sentinel.discover_master('mymaster') print(master) # 获取从服务器地址 slave = sentinel.discover_slaves('mymaster') print(slave) # 获取主服务器进行写入 master = sentinel.master_for('mymaster') master.set('foo', 'bar') # 获取从服务器进行读取(默认是round-roubin) slave = sentinel.slave_for('mymaster', password='redis_auth_pass') r_ret = slave.get('foo') print(r_ret)