4月更文d23n23-redis实现滑动窗口限流

194 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

利用redis实现滑动时间窗口限流

前文

本文主要内容为对于利用redis实现滑动窗口限流方案的讨论。当请求到达服务时,通过redis进行窗口限流操作,实现在给定的时间范围内,允许通过的请求数低于给定的允许通过上限数目。

滑动时间窗口

所谓滑动时间窗口,是一种时间窗口的概念。我们首先需要指定一个时间窗口的步长,其时间可能为t。则该窗口t的长度为保持不变的,但该窗口在时间轴上的位置则是向前推进的。利用请求举例来说,当请求到达时,我们需要保证请求前时间段t内曾发生的请求,要满足数量小于我们的限流请求数目。而当下一个请求到来时,则又重新根据请求时间计算出新的时间窗口。以此方式保证任意时间窗口的请求数都满足要求,并根据请求时间推进了窗口的滑动。

利用redis操作时间窗口

本方案主要是需要基于redis来解决滑动时间窗口的问题。首先我们需要选定一种redis的数据类型,这里我们采用sortedList。其中将存储的值设置为请求的身份信息,将排序的分值设置为实际的请求发生时间。下面来看一下实际的实现方案。

程序启动后首先需要在程序中指定滑动窗口的窗口范围,举例来说例如1秒。同时我们指定1秒内程序可以接收到的请求数量,例如100条。当请求到来时,首先到redis中获取我们已经存储好的排序列表。在其中读取满足当前时间1秒前发生的请求数目,并将其与100进行比较。如果数目超过100,则认为当前已达到请求上线,该请求废弃。反之则请求通过,将该请求信息写入到redis该key中。

看一个简单的流程图:

image.png

这是一个窗口时长为1秒的滑动窗口。0.3秒、1.2秒、1.55秒分别发生了三个请求。当1.55秒请求到达时,首先进行滑动窗口中的数据计算。0.3秒由于才窗口外被舍弃,1.2秒的数据在窗口内被保留。经过与预留的窗口上限请求数比较,确定该请求通过或被遗弃。

而在代码的操作中,主要采用zset的相关api进行处理即可,此处不进行赘述。

后记