首页 > 编程知识 正文

redis做限流,redis令牌桶限流算法

时间:2023-05-04 11:25:33 阅读:61757 作者:1275

《Redis 深度历险:核心原理和应用实践》一丝不苟的——漏斗限流是最常用的限流方法之一,顾名思义,该算法的灵感来源于漏斗的结构。

孔的容量有限。 堵住嘴,然后继续往里面加水,就会装满到再也进不去为止。 松开嘴,水往下流,流了一部分后,可以继续往里面倒水。 如果口漏的水的速度大于灌水的速度,漏斗就会永远不满。 当泄漏口流水速度小于灌水速度时,漏斗满时,灌水应暂停,等待漏斗放空

因此,漏斗剩馀空间表示当前行为可持续的数量,泄漏口的流水速度表示系统允许该行为的最大频率。 在这里,我们将使用代码来说明独立的算法。

publicclassfunnelratelimiter { staticclassfunnel { int capacity; 浮动学习速率; int leftQuota; 龙龙学习ts; 公共功能(int capacity,float leakingRate ) { this.capacity=capacity; this.leakingRate=leakingRate; this.leftQuota=capacity; this.leaking ts=system.current time millis (; } void makeSpace () longnowts=system.current time millis ); long deltaTs=nowTs - leakingTs; intDeltaquota=(int ) ) deltaTs * leakingRate; if(deltaquota0)//间隔时间过长,整数数字过大this.leftQuota=capacity; this.leakingTs=nowTs; 返回; (if ) deltaquota1) ) /太小以留出空间,最小单位为1 return; } this.leftQuota =deltaQuota; this.leakingTs=nowTs; if(this.leftquotathis.Capacity ) { this.leftQuota=this.capacity; 蓝牙(int quota ) { makeSpace ); if(this.leftquota=quota ) { this.leftQuota -=quota; 返回真; }返回假; } } private MapString,Funnel funnels=new HashMap (; publicbooleanisactionallowed (string userid,String actionKey,int capacity,float leakingRate ) string key=string.format fut if(funnel==null ) funnel=newfunnel(capacity,leakingRate ); funnels.put(key,funnel ); }returnfunnel.watering(1;//需要一个quota } } Funnel对象的make_space方法是漏斗算法的核心,每次灌水都会调用引起漏水,为漏斗留出空间。 能空出多少空间,取决于过了多久,以及流水的速度。 Funnel对象占用的空间大小与动作频率不成比例,其空间占用为常数。

问题是,分布式漏斗算法该如何实现? 可以使用Redis的基础数据结构解决吗? 查看Funnel对象的几个字段,可以将Funnel对象的内容按每个字段存储在一个散列结构中,灌水时取出散列结构的字段进行逻辑运算后,将新值回填到散列结构中,一次

但是有问题。 不能保证整个过程的原子性。 从混列结构取值,用存储器运算,回填到混列结构这三个过程不能原子化,意味着需要适当的锁定控制。 锁定意味着存在锁定失败,锁定失败必须选择重试或销毁。

重试会降低性能。 放弃的话,会影响用户体验。 同时,代码的复杂性也提高了很多。 这真是个艰难的选择。 怎样才能解决这个问题? Redis-Cell救星来了!

Redis-Cell此模块只有一个命令cl.throttle。 参数和返回值有点复杂。 接下来,让我们看看这个命令具体应该如何使用。

上述命令的含义是,允许“用户旧款回复行为”的频率为每60s最多30次(漏水速度),漏斗的初始容量为15。 也就是说,首先连续回复15篇投稿,然后可以开始受到漏水速度的影响。 此命令显示漏水速度为两个参数,而不是以前的单个浮点数。 用除以两个参数的结果来表现漏水速度,比单个浮点数更直观。

cl.throttle laoqian : reply 1530601 ((integer )0 # 0表示允许,1表示拒绝2 ) (integer ) 15 #漏斗容量capacity3) integer ) 14 )漏斗剩余空间) ) 652 cl.throttle命令非常睿智,可以计算到重试时间。 直接取返回结果数组中的第四个值sleep即可,如果不想阻止线程,也可以异步调度任务并重试。

考虑漏斗限流模块不仅适用于UGC,还适用于任何地方。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。