面试题答案
一键面试缓存策略实现限流
- 键值对设置:
- 键:可以使用API的唯一标识(如API路径、方法等组合)作为Redis的键。例如,对于一个GET请求的
/user/profile
API,键可以设置为api_limit:GET:/user/profile
。 - 值:值可以是一个计数器。每次请求到达时,对该计数器进行原子性的递增操作。
- 键:可以使用API的唯一标识(如API路径、方法等组合)作为Redis的键。例如,对于一个GET请求的
- 过期时间设置:
- 过期时间设置为限流的时间窗口。比如,限制每分钟最多100次请求,那么过期时间就设置为60秒。在过期时间内,通过计数器的值与限制的请求次数比较来判断是否限流。当过期时间到达后,计数器自动重置,开始新的时间窗口计数。
高并发场景下的优势
- 原子性操作:Redis支持原子性的递增操作(如
INCR
命令),在高并发场景下,多个请求同时尝试递增计数器时,不会出现竞争条件导致计数不准确的问题,保证了限流的准确性。 - 分布式特性:Redis天然支持分布式部署,适用于分布式系统中的API限流。多个服务实例可以共享同一个Redis缓存来进行限流,避免了在每个服务实例上单独实现限流可能带来的不一致问题。
- 性能高效:Redis基于内存存储,读写速度非常快,能够快速处理高并发的请求计数操作,不会因为限流逻辑而成为系统性能瓶颈。
可能存在的问题
- 缓存雪崩:如果大量API的缓存过期时间设置相同,在同一时刻缓存同时失效,可能会导致大量请求同时绕过限流,压垮后端服务。可以通过给过期时间加上一个随机偏移量来避免这种情况。
- 缓存穿透:如果恶意请求使用不存在的API标识来绕过限流,由于Redis中不存在对应的键,每次请求都不会命中缓存,从而绕过限流。可以通过在缓存中设置一个特殊标识(如 -1)来标记不存在的API标识,防止缓存穿透。
- 数据一致性问题:虽然Redis的原子操作保证了计数准确,但如果Redis与后端服务之间的数据同步出现问题,可能会导致实际限流效果与预期不一致。例如,Redis计数达到限流值,但后端服务没有及时感知到限流,仍然处理请求。需要通过合理的重试机制和监控来解决此类问题。