package
0.0.0-20241109021313-6e2457b08dcf
Repository: https://github.com/hjh0924/genericgo.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author

# README

基于 Redis + 滑动窗口 实现的限流器

Redis 命令解释

ZADD

Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。

如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。

分数值可以是整数值或双精度浮点数。

如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。

当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。

语法

ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN

返回值

被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。

示例

redis 127.0.0.1:6379> ZADD salary 2000 "tom"
(integer) 1
redis 127.0.0.1:6379> ZADD salary 3500 "peter"
(integer) 1
redis 127.0.0.1:6379> ZADD salary 5000 "jack" 3000 "Tvux"
(integer) 2
redis 127.0.0.1:6379> zrange salary 0 -1 withscores # 显示有序集内所有成员及其 score 值
1) "tom"
2) "2000"
3) "Tvux"
4) "3000"
5) "peter"
6) "3500"
7) "jack"
8) "5000"

ZCOUNT

Redis Zcount 命令用于计算有序集合中指定分数区间的成员数量。

语法

ZCOUNT KEY_NAME min max

返回值

分数值在 min 和 max 之间的成员的数量。

示例

redis 127.0.0.1:6379> ZCOUNT salary 2000 5000
(integer) 4

ZCARD

Redis Zcard 命令用于计算集合中元素的数量。

语法

ZCARD KEY_NAME

返回值

当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0 。

示例

redis 127.0.0.1:6379> ZCARD salary
(integer) 4

ZCOUNT key -inf +infZCARD key 在某种程度上是等价的,但它们在行为上有细微的差别。

  1. ZCOUNT key -inf +inf:
    • ZCOUNT 命令用于计算有序集合中,分数(score)在给定区间内的成员数量。
    • 当你使用 -inf +inf 作为区间时,它意味着你正在计算集合中所有成员的数量,因为 -inf 表示负无穷大,+inf 表示正无穷大,所以这个区间涵盖了所有可能的分数。
  2. ZCARD key:
    • ZCARD 命令用于返回有序集合中的成员数量。
    • 它直接返回集合中的成员总数,而不需要指定分数区间。

尽管两者都返回有序集合中的成员数量,但 ZCOUNT 命令在执行时会检查分数区间,而 ZCARD 则直接返回计数。在实际使用中,如果你只是想知道集合中的成员数量,使用 ZCARD 会更高效,因为它不需要进行分数区间的检查。

在限流器的上下文中,如果你的目的是检查某个 IP 在当前时间窗口内的请求次数是否超过了阈值,并且你已经确保了时间窗口内的请求都被记录在了有序集合中,那么使用 ZCARD 会更合适,因为它直接返回了集合的大小,而不需要额外的区间检查。

总结来说,如果你不需要考虑分数区间,只是想要得到有序集合的成员数量,那么 ZCARD 是一个更简单、更高效的选择。

ZREMRANGEBYSCORE

Z - 有序集合 REM - remove 移除 RANGE - range 排序 BYSCORE - by score 按照分数

Redis Zremrangebyscore 命令用于移除有序集中,指定分数(score)区间内的所有成员。

语法

ZREMRANGEBYSCORE KEY_NAME min max

返回值

被移除成员(member)的数量。

示例

redis 127.0.0.1:6379> ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工
(integer) 3

redis> ZRANGE salary 0 -1 WITHSCORES  # 剩下的有序集成员
1) "jack"
2) "5000"

PEXPIRE

Redis PEXPIRE 命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。

语法

PEXPIRE KEY_NAME milliseconds

返回值

设置成功,返回 1

key 不存在或设置失败,返回 0

示例

redis 127.0.0.1:6379> SET mykey "Hello"
"OK"
redis 127.0.0.1:6379> PEXPIRE mykey 1500
(integer) 1
redis 127.0.0.1:6379> TTL mykey
(integer) 1
redis 127.0.0.1:6379> PTTL mykey
(integer) 1498

实现 - IP限流器

基于 Redis 和 滑动窗口 实现的 IP 限流器通常使用 Redis 的有序集合(sorted set)来存储每个 IP 地址的请求时间戳。每个请求都会被添加到这个集合中,并且使用当前时间戳作为分数。通过这种方式,可以快速地检查一个 IP 在给定的时间窗口内是否超过了请求次数的限制。

假设现在要限制每个IP地址每秒最多100个请求,则

  • 限流对象:IP地址
  • 时间窗口:1s
  • 请求阈值:100
  • 分数:当前时间戳
  • 成员:当前时间戳

Lua 脚本用于原子性地执行Redis的以下操作:

  • 移除时间窗口之外的旧请求。
  • 检查当前时间窗口内的请求数量是否超过了阈值。
  • 如果没有超过阈值,记录新的请求。