首页 > 数据库 >Redis 利用 incr 和 expire 来限流, 并发导致过期时间失效问题

Redis 利用 incr 和 expire 来限流, 并发导致过期时间失效问题

时间:2022-12-05 13:33:10浏览次数:55  
标签:incr Redis redis 限流 key query data

当某一个接口需要限流时,可以采用redis的incr来递增,记录访问次数, 以及 expire 来设置失效时间.
大概的代码如下:

    r = redis.Redis.connect()
    key = "linyk3"
    query_times = redis.Redis.get_data(r, key)
    if query_times and int(query_times) > 1000:
        print('访问次数过多,超过1000次限制!')
        return
    else:
        redis.Redis.incr(r, key)
        if redis.Redis.get_data(r, key) == 1:
            redis.Redis.expire_data(r, key, 60*60)

 

因为redis的incr操作,当key不存在时, 会生成这个key并将值初始化为0, 并且默认设置key的有效时间为长期.
这样上面的代码就基本可以限制住访问次数,并在1小时内失效,允许重新访问.

但是在高并发的情况下,当某进程查询key不存在,所以执行了上面的incr后,会将值初始化为0,
假如进程1执行了incr, 将key对应的值递增为1,这时在进程1执行 if redis.Redis.get_data(r, key) == 1: 判断前, 进程2也执行了incr,这时key对应的值就会被递增为2, 然后进程1在判断 if redis.Redis.get_data(r, key) == 1: 会发现2 !=1, 所有不会设置过期时间,这样这个访问就会一直被拒绝了.

解决方法:
当获取key为None时, 创建key,并直接设置失效时间:

    r = redis.Redis.connect()
    key = "linyk3"
    query_times = redis.Redis.get_data(r, key)
    if not query_times:
        redis.Redis.incr(r, key)
        redis.Redis.expire_data(r, key, 60 * 60)
    elif int(query_times) > 1000:
        print('访问次数过多,超过1000次限制!')
        return 
    else:
        redis.Redis.incr(r, key)

 

https://www.jianshu.com/p/31a42f8f834a        

 

标签:incr,Redis,redis,限流,key,query,data
From: https://www.cnblogs.com/softidea/p/16952039.html

相关文章

  • redis快速入门
    ​​https://gold.xitu.io/post/5880590d1b69e60058c72803​​​解压后的安装#make指定安装目录:#makePREFIX=/usr/local/redisinstall进入/......
  • 数据库缓存服务——NoSQL之Redis配置与优化
    缓存概念缓存是为了调节速度不一致的两个或多个不同的物质的速度,在中间对速度较慢的一方起到加速作用,比如CPU的一级、二级缓存是保存了CPU最近经常访问的数据,内存是保存C......
  • (收藏)接口限流实践
    一、问题描述 某天A君突然发现自己的接口请求量突然涨到之前的10倍,没多久该接口几乎不可使用,并引发连锁反应导致整个系统崩溃。如何应对这种情况呢?生活给了我们答案:比......
  • 非关系型数据库redis部署及优化
    一,关系型数据库与非关系型数据库1.关系型数据库一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录SQL语句(标准数据查询语言)就是一种基于关系型数据......
  • 详解 Redis 中 big keys 发现和解决
    在使用Redis时,可能会出现请求响应慢、网络卡顿、数据丢失的情况。排查问题的时候,发现是bigkeys的问题。什么是bigkeys在Redis中,一个字符串类型最大可以达到512......
  • day23 --> (redis)
    Redis: 1.概念:redis是一款高性能的NOSQL系列的非关系型数据库2.下载安装:1、官网:https://redis.io2、中文网:http://www.redis.net.cn/3.解压可以直接使用:redis.wi......
  • Redis命令
    https://blog.csdn.net/m0_64830623/article/details/123145942启动主master:redis-server/Users/macos/IDEA_Project/redis/redis-6.0.16/redis.conf启动slave:redis-ser......
  • 如何使用Redis做缓存
    如何使用Redis做缓存我们都知道Redis作为NoSql数据库的代表之一,通常会用来作为缓存使用。也是我在工作中通常使用的缓存之一。1、我们什么时候缓存需要用到Redis?我认为,......
  • 领券中心项目,如何用 Redis 做实时订阅推送的?
    领券中心项目,如何用Redis做实时订阅推送的? 其中有一个功能叫做领劵的订阅推送。什么是领劵的订阅推送?就是用户订阅了该劵的推送,在可领取前的一分钟就要把提醒信息......
  • redis之缓存问题
    一缓存穿透1什么是缓存穿透缓存穿透是指查询一个在redis和DB中都不存在的数据,redis中查不到去DB查,DB查不到则不写入redis,导致每次查询这个数据都要穿过redis穿透到DB......