面试题答案
一键面试方案设计思路
- 基本原理:滑动窗口限流是将时间窗口划分为多个子窗口,通过统计每个子窗口内的请求数量来进行限流。对于业务流量有波峰波谷且限流规则不同的场景,我们可以根据不同时间段设置不同大小的子窗口以及不同的限流阈值。
- 波峰处理:在波峰时间段,由于流量大,为了更精细地控制流量,子窗口可以划分得较小,这样能更实时地监控请求数,避免瞬间流量过大突破限流。
- 波谷处理:在波谷时间段,流量相对较小,子窗口可以划分得较大,减少不必要的统计开销。
使用的Redis命令及数据结构
- 数据结构:使用Redis的有序集合(Sorted Set)来存储每个子窗口的请求计数。有序集合的成员(member)可以设置为子窗口的标识(例如时间戳),分值(score)设置为子窗口的开始时间,这样可以方便地根据时间顺序对窗口进行排序和查询。
- Redis命令:
- ZADD:用于向有序集合中添加子窗口的请求计数。例如,
ZADD key score member
,这里key
是限流的标识,score
是子窗口的开始时间,member
可以是子窗口内请求计数的标识(如count:timestamp
)。每次有请求进来,先计算当前请求所属子窗口的时间标识,然后使用ZADD
命令更新该子窗口的请求计数。 - ZRANGEBYSCORE:用于获取某个时间段内所有子窗口的请求计数总和。例如,
ZRANGEBYSCORE key min max WITHSCORES
,min
和max
分别是滑动窗口的起始和结束时间,通过获取这些子窗口的计数总和与限流阈值比较,来判断是否限流。
- ZADD:用于向有序集合中添加子窗口的请求计数。例如,
动态调整子窗口划分以适应业务流量变化
- 流量监控:通过定期统计一段时间内的请求总量,判断当前处于波峰还是波谷。例如,每5分钟统计一次过去1小时内的总请求数,与预先设定的波峰、波谷阈值比较。
- 调整策略:
- 进入波峰:如果检测到进入波峰,将子窗口划分得更小。例如,原本子窗口为1分钟,调整为10秒。首先,根据新的子窗口大小重新计算每个请求所属的子窗口标识。然后,将原有序集合中的数据按照新的子窗口进行重新统计和存储。可以通过遍历原有序集合,根据新子窗口大小重新分组计算请求计数,再使用
ZADD
命令更新到新的有序集合中。 - 进入波谷:如果检测到进入波谷,将子窗口划分得更大。例如,原本子窗口为1分钟,调整为5分钟。同样需要重新计算请求所属子窗口标识,并对原有序集合数据进行重新统计和存储,以适应新的子窗口划分。
- 进入波峰:如果检测到进入波峰,将子窗口划分得更小。例如,原本子窗口为1分钟,调整为10秒。首先,根据新的子窗口大小重新计算每个请求所属的子窗口标识。然后,将原有序集合中的数据按照新的子窗口进行重新统计和存储。可以通过遍历原有序集合,根据新子窗口大小重新分组计算请求计数,再使用