python操作redis常用到的方法

之前有在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"))

打印如下

{6DD90058-E999-41A5-8D06-32DF638D2690}_20190505134239.jpg

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"))

{26C6E01E-E68E-4108-82AA-7241B9D43C0A}_20190505135636.jpg

我们看到设置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)


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://sulao.cn/post/657.html