Redis简易应用实现

Redis简单应用

代码如下:

import random
import redis
import pickle


REDIS_HOST = '10.30.133.13'
REDIS_PASSWORD = 'MzhhMzU4NDQzNzU'
REDIS_PORT = 6379


class RedisClient(object):
    def __init__(self):
        redis_pool = redis.ConnectionPool(host=REDIS_HOST, password=REDIS_PASSWORD, port=REDIS_PORT)
        self.client = redis.Redis(connection_pool=redis_pool)

    def get(self, key):
        try:
            return pickle.loads(self.client.get(key))
        except Exception as ex:
            return None

    def set(self, key, value, **kwargs):
        """
        ex: 过期时间 秒s
        px: 过期时间 毫秒ms
        nx: 键不存在时生效
        xx: 键存在时生效
        """
        if not kwargs.get('ex') and not kwargs.get('px'):
            # 不允许设置永久KEY,未设置失效时间的,则默认设置为 12-24 hour
            kwargs['ex'] = random.randint(12 * 60 * 60, 24 * 60 * 60)

        try:
            self.client.set(key, pickle.dumps(value), **kwargs)
            return self.get(key)
        except Exception as ex:
            return None

    def ttl(self, key):
        """
        键不存在时:return -2
        未设置生命周期时:return -1
        """
        return self.client.ttl(key)

    def incr(self, key):
        """
        自增+1,如果key不存在,则默认设置一个有失效时间的key(官方默认生命周期为-1,永久有效)
        """
        if self.ttl(key) in [-1, -2]:
            self.set(key, self.client.get(key) or 0, ex=random.randint(1, 3))

        try:
            return self.client.incr(key)
        except:
            return None

    def scan(self, **kwargs):
        """
        根据正则匹配对应keys
        """
        _keys = self.client.scan(**kwargs)
        keys = list()

        for item in _keys[1]:
            if isinstance(item, bytes):
                keys.append(item.decode('utf-8'))

        return keys

    def keys(self):
        """
        获取所有key
        """
        return self.client.keys()

    def destroy(self, key):
        try:
            return self.client.delete(key)
        except Exception as ex:
            pass

    def match_destroy(self, pattern):
        """
        根据正则匹配删除
        """
        keys = self.scan(match=pattern)

        for key in keys:
            self.destroy(key)

        return keys

    def session(self, is_class=False):
        """
        is_class: 是否为类方法
        目的:提供redis实例供方法直接使用
        """
        def wrapper(func):
            def exec(*args, **kwargs):
                if not is_class:
                    return func(self, *args, **kwargs)

                _args = list(args)
                func_instance = _args.pop(0)
                # 处理位置参数传参错乱问题
                return func(func_instance, self, *_args, **kwargs)

            return exec

        return wrapper

    def session_method(self, key, expires=60):
        """
        针对方法进行缓存,value为方法返回值
        """
        def wrapper(func):
            def exec(*args, **kwargs):
                func_key = f'{str(func.__qualname__)}_{key}'
                value = self.get(func_key)
                if value is not None:
                    return value

                value = func(*args, **kwargs)
                self.set(func_key, value, ex=expires)

                return value
            return exec

        return wrapper


if __name__ == '__main__':
    redis_client = RedisClient()
    # 写入key
    redis_client.set(key='thisiskey', value='thisisvalue', ex=60)
    # 读取key
    print(f'value={redis_client.get("thisiskey")}')
    # 获取失效时间
    print(f'ttl={redis_client.ttl("thisiskey")}')
    # 扫描keys
    print(f'scan={redis_client.scan(match="thisiskey")}')
    # 删除keys
    print(f'delete_key={redis_client.match_destroy("this*")}')
    print(f'value={redis_client.get("thisiskey")}')

result:
在这里插入图片描述

进阶应用(高级感)

实例1:使用装饰器注入redis实例(方法)

redis_client = RedisClient()

@redis_client.session()
def test1(session, *args, **kwargs):
    session.set('thisiskey', 'thisisvalue')

    return session.get('thisiskey')

print(test1())

result:
在这里插入图片描述

实例2:使用装饰器注入redis实例(类方法)

redis_client = RedisClient()

class Test(object):
    @redis_client.session(is_class=True)
    def test2(self, session):
        session.set('thisiskey', 'thisisvalue')

        return session.get('thisiskey')

print(Test().test2())

实例3:使用装饰器对方法返回值进行缓存,针对被频繁调用的方法

redis_client = RedisClient()

class Test(object):

    @redis_client.session_method('thisiskey_test3', 60)
    def test3(self, **kwargs):
        print('i am here')
        return 'thisisvalue_test3'


print(Test().test3())
print(Test().test3())

result:
在这里插入图片描述
实例4:使用redis进行接口限流
推荐使用

https://editor.csdn.net/md/?articleId=131138755

例如上传文件接口,同一用户仅允许10s内上传一次

redis_client = RedisClient()

@redis_client.session()
def import_file_limit(session, request):
    key = f'{request.method}_{request.path}_{request.user_id}_import_file'
    session.set(key, 0, ex=10, nx=True)
    num = session.incr(key)

    if num <= 1:
        return

    ttl = session.ttl(key)

    print(f'{request.user_id}提交过于频繁,请在 {ttl} 秒后重试')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值