跳到主要内容

认识

2025年01月06日
柏拉文
越努力,越幸运

一、认识


在实际开发中,Redis 的计数限流是一种常用的限流策略,利用 Redis 的高性能计数 Increment 功能实现对请求频率的限制。常见的实现方式有 固定窗口滑动窗口

场景如下:

  1. API 限流:限制某个用户或 IP 在一定时间窗口内的请求次数,防止接口被滥用。

  2. 短信发送频率限制:控制用户在一定时间内发送短信的次数。

  3. 登录保护:限制用户登录尝试次数,防止暴力破解。

  4. 秒杀活动防刷:限制单个用户在秒杀活动中的请求频率。

  5. 分布式限流:在分布式系统中对某类请求进行全局限流。

思路如下:

  1. 定义时间窗口:如 1 秒、1 分钟、1 小时等。

  2. 记录请求次数:为用户或 IP 创建一个唯一标识,在 Redis 中存储请求计数。

  3. 设置过期时间:为计数键设置 TTL,与时间窗口保持一致。

  4. 检查计数限制:请求时检查计数是否超过阈值,超限则拒绝请求。

Redis 计数限流 可以基于 Redis 是内存数据库,读写速度极快,适合高并发场景等特点能够很好地解决高并发和滥用问题,并且简单高效,可以按用户、IP、接口动态调整限流规则。

Redis 计数限流固定窗口: 固定窗口限流 将时间划分为固定大小的时间段(如每分钟、每秒),在每个时间段内限制请求次数。当进入下一个时间段时,计数器会重置。具体步骤为: 在 Redis 中为每个用户或操作创建一个计数器键,键名包含时间窗口标识(如时间戳)。当用户发起请求时, 如果键不存在,则创建键并设置初始值为 1,并设置过期时间(等于窗口时长)。如果键已存在,则递增计数器。如果计数器值超过限制,拒绝请求。在固定时间窗口中,限流逻辑可能会出现的问题为: 如果窗口周期结束,计数会立即重置,可能导致流量突增。例如,某 API 每分钟限流 100 次,可能在最后一秒发送 100 次请求,而在下一秒又发送 100 次请求,导致 200 次请求集中在 2 秒内完成。对于精度要求较高的场景,这种计数方式可能不够精确。

Redis 计数限流互动窗口: 滑动窗口 通过更精细化的时间统计解决固定窗口的临界问题。它利用 Redis 有序集合(ZSET)存储请求的时间戳,并动态调整统计范围,使得时间窗口可以 滑动具体步骤为: 为每个用户或操作通过 ZADD 创建一个有序集合键,值为请求的时间戳。当用户发起请求时, 添加当前时间戳到有序集合,通过 ZREMRANGEBYSCORE 删除集合中超出时间窗口范围的旧时间戳, 通过 ZCARD 获取集合中当前时间窗口内的元素数量, 如果数量超过限制,拒绝请求, 并设置键的过期时间, 避免无用数据长期占用存储。滑动窗口 可以实现精细化统计,能够更精确地限制请求频率,避免流量突增,解决了固定窗口的临界问题,限流更加平滑,时间粒度更加精细。并具有高灵活性,可适用于更高要求的限流场景,例如对实时性要求较高的 API。而且可以动态调整,可以灵活调整时间窗口和请求限制。