「Redis应用」Redis ”高级“应用场景 -- 限流、延时队列、幂等处理

本文探讨了Redis在限流、延时队列和幂等处理中的应用场景。文章详细介绍了固定窗口计数和滑动窗口计数两种限流方法及其Redis实现,讨论了漏桶算法和令牌桶算法的原理和区别。接着,文章讨论了如何使用Redis实现延时队列,分析了String和ZSet两种方法的优缺点。最后,文章提到了使用Redis实现幂等处理的策略,以及 incr 操作在签到计数和登录失败防护中的应用。
摘要由CSDN通过智能技术生成

引言

自Redis入门篇过后,已经好久没更Redis了,接下来应该从实战篇,原理篇,面试篇几个层次来展开,本篇主要是实战篇环节,以问题展开,应对面试场景作答【melo称其为"手撕面答"】,尽量简短,某些部分可能不会进行详细介绍。

emmm,但后边有些部分还是干脆整合在一起了,可观性好一点,不至于看得一头雾水

🎨本篇脑图速览

🎯🎈Redis限流是怎么做的?

固定窗口计数

固定窗口计数是指,假设我们的限流规则是:1min内最多只能访问10次,那么固定窗口就是固定了【 1min-2min】这个窗口内,只能有10次访问 ,相应的我们就要给这个窗口维护一个计数器。 为了节省空间,其实我们不需要维护一个个窗口,只需要维护当前访问时间所在的窗口即可,以及对应的计数器,当新的访问到达了下一个窗口时,则计数器重置即可

redis实现

用redis的话,由于有过期机制,其实设置1min过期,就可以实现计数器重置的效果了

  • redis设置一个名为qps的key,val用来计数,1min过期即可
//原子自增类
RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(redisKey, redisTemplate.getConnectionFactory());
//先自增
int qps = redisAtomicInteger.getAndIncrement();
//若是第一次访问
if(qps==0){
    //设置1min过期
	redisAtomicInteger.expire(1, TimeUnit.MINUTES);
}
if(qps>10){
	throw new RuntimeException("qps超过阈值");
}
复制代码

存在的问题

由于是固定窗口,那其实存在窗口临界问题,比如用户可以在【1.5-2】这段区间访问10次,【2-2.5】这段区间也访问10次,这样就变成了1min内其实可以访问20次!看起来破坏了我们的限流规则,但由于我们是固定窗口计数,到达2的时候已经重置计数器了。

滑动窗口计数

假设我们的限流规则是:1min内最多只能访问10次,那么滑动窗口呢就是会根据你访问进来的时间,以访问时间作为区间末尾当前时间-1min作为区间头部,相当于窗口一直在往右滑动,这样其实就能在一定程度上解决我们刚才提到的窗口临界问题

  • 当访问时间为2.5的时候,此时对于的窗口是【1.5-2.5】,计数器都能正确计数

实现

要获得一段区间,并且按时间排序,我们可以想到用ZSet来实现,能按区间查询出【当前访问时间-1min,当前访问时间】这段区间的计数

//interMills为限流时间,也就是我们这里的1min
Long count = redisTemplate.opsForZSet().count(redisKey, currentTimeMillis - interMills, currentTimeMillis);
复制代码

存在的问题

其实我们只是以更小的窗口大小去移动这个区间罢了,固定窗口计数是以1min为单位去移动,滑动窗口是以1s为单位去移动,后者出现窗口临界问题的概率更小,但依然是可能出现的,比如:

  1. 一开始是【1-2min】这段区间,下一秒会移动为【1min1s - 2min1s】,如果此时有人在1min这一刻,访问了10次,然后下一秒又进入下一个区间了,计数重置,在1min1s这一刻又访问了10次,依旧会出现窗口临界问题,1min内访问次数达到了20次

窗口临界问题小结

其实窗口临界问题,就是在即将被移出窗口的这段区间内,可能一次性访问量达到了我们的阈值,而由于要移出窗口了,计数又将重置了,所以这些访问量就相当于不会被后续统计到,那么后续再次超过阈值,就变成双倍阈值了。

漏桶算法

不限制流入,只限制流出的速率 -- 以一定的速率,去获取桶中的请求

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值