python操作redis
前言
主要是介绍 python 操作 redis 的有序集合,以及使用 redis 实现分布式锁的功能。
一、redis 中的有序集合
有序集合是一种数据类型,类似于集合和哈希之间的混合。像集合一样,排序集由唯一的,非重复的字符串元素组成,因此从某种意义上说,有序集合也是一个集合。 但是,虽然集合内的元素没有排序,但排序后的集合中的每个元素都与一个称为得分的浮点值相关联(这就是为什么该类型也类似于哈希的原因,因为每个元素都映射到一个值)。 此外,有序集合中的元素是按顺序进行的(因此,它们不是应请求而排序的,顺序是用于表示已排序集合的数据结构的特殊性)
二、redis常见的有序集合的指令
1.连接redis
代码如下(示例):
import redis
r = redis.Redis(**config.REDIS_CONF)
2. zadd
添加到有序set的一个或多个成员,或更新的分数,如果它已经存在
代码如下(示例):
redis.zadd('my-key', 'name1', 1.1, 'name2', 2.2, name3=3.3,name4=4.4)
3. zrangebyscore
返回有序集合中指定分数区间内的成员,分数由低到高排序。
代码如下(示例):
r.zrangebyscore(name, min, max, start=None, num=None,
withscores=False, score_cast_func=float)
如果指定了’ ’ start ’ ‘和’ num ’ ',则返回一个片
的范围内。
’ ’ withscores ’ '表示返回分数和值。
返回类型是(值、分数)对的列表
’ score_cast_func ’ '一个可调用函数,用于转换分数返回值
4. zrange
返回排序集’ ’ name ’ ‘之间的值范围’ ’ start ’ ‘和’ ’ end ’ '按升序排列。
代码如下(示例):
zrange(self, name, start, end, desc=False, withscores=False,score_cast_func=float):
’ start ’ ‘和’ ’ end ’ '按升序排列。
start
和end
可以是负的,表示范围的结束。
’ ’ desc ’ '一个布尔值,指示是否对结果进行向下排序
’ ’ withscores ’ '表示返回分数和值。
返回类型是(值、分数)对的列表
’ ’ score_cast_func ’ '一个可调用函数,用于转换分数返回值
三、利用 redis 实现分布式锁
写了分布式锁代码,做成了一个装饰器
def check_lock(func_or_cls):
"""
redis分布式锁
:param func_or_cls:
:return:
"""
def wapper(self, *args, **kwargs):
job_lock = r.set(self.lock_name, 1, ex=60, nx=True)
if job_lock is True:
try:
res = func_or_cls(self, *args, **kwargs)
except Exception:
res = None
r.delete(self.lock_name)
return res
else:
pass
return wapper
使用方式:
class MqMessageHandler(object):
"""每个topic对应的操作"""
@staticmethod
def topic_call_back(msg):
"""
订阅topic之后的操作
:param msg:
:return:
"""
Loggers(log_name='MqMessageHandler')
flag, text_json = bytes_to_dict(msg.body) # 将bytes类型转换成字典类型
logging.info({"msg_id": msg.id, "msg_body": msg.body, "text_json": text_json})
now_date = Utils.get_date_str().replace("-", "") # 获取当天日期
now_time = Utils.timestamp_second()
if msg.body == b'OK':
refresh_key = f"media_auth_refresh_{now_date}"
r.zadd(refresh_key, now_time, 0) # 加入有序集合 key 当前时间 分数(0表示需要有新的动作)
elif flag:
new_key = f"media_auth_new_{now_date}"
r.zadd(new_key, text_json, 0)
else:
logging.error({"msg_id": msg.id, "msg_body": msg.body})
主要是借助 set 方法实现锁,set方法的详细说明如下:
def set(self, name, value, ex=None, px=None, nx=False, xx=False):
"""
Set the value at key ``name`` to ``value``
``ex`` sets an expire flag on key ``name`` for ``ex`` seconds.
``px`` sets an expire flag on key ``name`` for ``px`` milliseconds.
``nx`` if set to True, set the value at key ``name`` to ``value`` only
if it does not exist.
``xx`` if set to True, set the value at key ``name`` to ``value`` only
if it already exists.
"""
是借助 nx 这个参数的特性,如果设置 nx=True ,则只有当这个name对应的value不存在才会返回True