主流的几种限流策略,我都可以通过python+redis实现

本文介绍了限流在高并发系统中的重要性,并通过Python和Redis实现了几种常见的限流算法,包括固定窗口法、滑动窗口法、令牌桶法和漏桶算法。详细解释了各种算法的工作原理和优缺点,最后提到了Redis的Cell模块作为简化限流实现的工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

保护高并发系统的三大利器:缓存、降级和限流

那什么是限流呢?用我没读过太多书的话来讲,限流就是限制流量。

我们都知道服务器的处理能力是有上限的,如果超过了上限继续放任请求进来的话,可能会发生不可控的后果。

而通过限流,在请求数量超出阈值的时候就排队等待甚至拒绝服务,就可以使系统在扛不住过高并发的情况下做到有损服务而不是不服务。

举个例子,如各地都出现口罩紧缺的情况,武汉政府为了缓解市民买不到口罩的状况,上线了预约服务,只有预约到的市民才能到指定的药店购买少量口罩。

这就是生活中限流的情况,说这个也是希望大家这段时间保护好自己,注意防护 :

接下来就跟大家分享下接口限流的常见玩法吧,部分算法用python + redis粗略实现了一下,关键是图解啊!你品,你细品~

固定窗口法

固定窗口法是限流算法里面最简单的,比如我想限制1分钟以内请求为100个,从现在算起的一分钟内,请求就最多就是100个,这分钟过完的那一刻把计数器归零,重新计算,周而复始。在这里插入图片描述
伪代码实现

def can_pass_fixed_window(user, action, time_zone=60, times=30):
    """
    :param user: 用户唯一标识
    :param action: 用户访问的接口标识(即用户在客户端进行的动作)
    :param time_zone: 接口限制的时间段
    :param time_zone: 限制的时间段内允许多少请求通过
    """
    key = '{}:{}'.format(user, action)
    # redis_conn 表示redis连接对象
    count = redis_conn.get(key)
    if not count:
        count = 1
        redis_conn.setex(key, time_zone, count)
    if count < times:
        redis_conn.incr(key)
        return True

    return False

这个方法虽然简单,但有个大问题是无法应对两个时间边界内的突发流量。如上图所示,如果在计数器清零的前1秒以及清零的后1秒都进来了100个请求,那么在短时间内服务器就接收到了两倍的(200个)请求,这样就有可能压垮系统。会导致上面的问题是因为我们的统计精度还不够,为了将临界问题的影响降低,我们可以使用滑动窗口法。

滑动窗口法

滑动窗口法,简单来说就是随着时间的推移,时间窗口也会持续移动,有一个计数器不断维护着窗口内的请求数量,这样就可以保证任意时间段内,都不会超过最大允许的请求数。例如当前时间窗口是0s~60s,请求数是40,10s后时间窗口就变成了10s~70s,请求数是60

时间窗口的滑动和计数器可以使用redis的有序集合(sorted set)来实现。score的值用毫秒时间戳来表示,可以利用 当前时间戳- 时间窗口的大小 来计算出窗口的边界,然后根据score的值做一个范围筛选就可以圈出一个窗口;value的值仅作为用户行为的唯一标

### Redis 使用场景 Redis 是一种高性能的键值对数据库,支持丰富的数据结构操作。其典型的应用场景包括但不限于以下几个方面: 1. **缓存** Redis 常被用作缓存层,用于加速应用的数据访问速度。它可以通过存储热点数据减少对后端数据库的压力[^2]。常见的缓存问题如缓存穿透、缓存击穿和缓存雪崩都可以通过合理的设计解决。 2. **分布式锁** 利用 Redis 提供的原子命令(如 `SETNX`),可以实现高效的分布式锁机制。此外,第三方库如 Redisson 进一步简化了分布式锁的开发过程。 3. **计数器与统计** Redis 可以轻松实现各种实时统计数据的需求,比如全局 ID 生产、用户行为统计以及位图分析等[^3]。 4. **消息队列** 通过列表(List)数据结构,Redis 能够充当简单的消息队列系统。配合发布/订阅模式(Pub/Sub),还可以构建更复杂的消息通知功能。 5. **延迟队列** 结合 Lua 脚本或者有序集合(Sorted Set),Redis 实现了灵活的任务调度能力,适用于订单超时取消等功能。 6. **排行榜** 排行榜类的功能非常适合基于 Redis 的 ZSet 数据类型完成,因为它允许按分数排序并高效查询排名范围内的成员。 7. **限流** 对于保护服务免受突发流量冲击而言,采用令牌桶或漏斗算法结合 Redis 存储状态是一种常见做法[^4]。 --- ### Redis 的优势 以下是使用 Redis 的主要好处: #### 性能卓越 - Redis 所有操作都在内存中执行,因此具备极高的读写效率,每秒可处理数十万次请求[^1]。 #### 多样化的数据模型 - 支持字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)及有序集(ZSets/Sorted Sets),满足不同类型业务逻辑需求。 #### 持久化选项 - 提供 RDB 和 AOF 两种持久化方式,在断电或其他异常情况发生时仍能恢复大部分甚至全部数据。 #### 主从复制与集群扩展 - 自带主从同步特性便于搭建高可用架构;同时官方推出的 Cluster 解决方案让水平扩容变得可行。 #### 易用性强 - API 设计简洁直观,几乎任何主流编程语言都有对应的客户端库可供选用。 尽管如此,也需要注意潜在局限之处,像单机版存在单点风险等问题可通过引入 Sentinel 或者 Cluster 来缓解。 ```python import redis # 创建连接池实例 pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) # 获取 Redis 客户端对象 r = redis.StrictRedis(connection_pool=pool) # 设置 key-value 并指定存活时间为 10 秒钟 r.set('test_key', 'value', ex=10) print(r.get('test_key')) # 输出 value ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值