工作日常记录


前言

主要是介绍 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 ’ '按升序排列。

startend可以是负的,表示范围的结束。

’ ’ 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


版权声明:本文为weixin_39752185原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。