redis lua限流算法实现示例

目录

限流算法

计数器算法

场景分析

算法实现

漏铜算法

令牌桶算法:

算法实现

限流算法

常见的限流算法

计数器算法

漏桶算法

令牌桶算法

计数器算法

  顾名思义,计数器算法是指在一定的时间窗口内允许的固定数量的请求.比如,2s内允许10个请求,30s内允许100个请求等等.如果设置的时间粒度越细,那么相对而言限流就会越平滑,控制的粒度就会更细.

场景分析

试想,如果设置的粒度比较粗会出现什么样的问题呢?如下图设置一个 1000/3s 的限流计数统计.

图中的限流策略为3s内允许的最大请求量为1000,那么会出现2个极端:
 

极端情况1:

第1s请流量为10,  

第2s请流量为10,  

第3s请流量突然激增到980.这意味着在这一刻,有大量的请求蜂拥而至,假设服务每秒能处理的

上线为800/1s,但是此刻却有超过这个量级的请求量,那么后果是不堪设想的.

极端情况2:  

第1s请流量突然就达到990,

留给后续第2s,3s的可请求数量就非常少了,可能会出现大量的拒绝请求.

结论:

如果用统计计数算法,尽量保持粒度切割精细.

算法实现

redis的ttl特性完美的满足了这一需求,将时间窗口设置为key的失效时间,然后将key的值每次请求+1即可.伪代码实现思路:

//1.判断是否存在该key if(EXIT(key)){ // 1.1自增后判断是否大于最大值,并返回结果 if(INCR(key) > maxPermit){ return false; } return true; } //2.不存在key,则设置key初始值为1,失效时间为3秒 SET(KEY,1); EXPIRE(KEY,3); 漏铜算法

漏桶算法核心概念:

桶的容量是固定的,并且水流以一个固定的速率流出;

流入的水流可以是任意速率;

如果流入的水流超出了桶的容量,则后续流入的水流溢出(请求被丢弃)。

如果桶内没有水,则不需要流出

缺点:

不难想象漏桶算法并不能很好的应对突发的流量限制,在某一个时间段流量激增,则漏桶算法处理就比较无能为力.这个时候就需要用到和他相反设计的令牌桶算法

令牌桶算法:

如上图所示,整个请求流程一目了然.简单概括如下:

1.用户请求资源时首选从桶里获取令牌,如果有令牌则放行,如此同时桶里的令牌数量-1

2.于此同时,以一定的速率往桶里加入令牌,这个速度是可根据实际场景随意设置.

算法实现 var key; var maxPermit;//桶的容量,即最大请求限制 var expire;//失效时间 var bucketInterval;//每次向桶里添加令牌的时间间隔 var bucketNum;//每次向桶里添加令牌的个数 var lastTimeKey = key +"last";//标记上一次操作时间 //判断是否存在该key if(EXIT(key)){ var value = GET(key); var diffTime = now() - lastTimeKey; // 1.1判断是否超出时间间隔 if(diffTime > bucketInterval){ // 1.2根据时间间隔,计算出应该向桶里添加令牌的个数 local maxValue = value+math.floor(diff/interval)*step; if (maxValue > limit) value = limit; else value = maxValue; //设置key的值及操作时间 SET(key,value); SET(lastTimeKey,now()); } // 2.1在时间间隔内,判断桶里是否有值 if(value <= 0){ reurn false; }else{ // 2.2 减1 DECR(key); } reture true; } //2.不存在key,则设置key初始值为maxPermit-1 SET(key,maxPermit-1); EXPIRE(lastTimeKey,now());

上面实现代码只是伪代码,提供的是一种思路而已. 仔细想来其中某个环节其实并不完美.大家可以参考Guava的ratelimit实现思路,他的限流就是基于令牌桶算法,但是比较遗憾的是在单机下的限流.

思考:  

就是时间间隔如果过长的话,一次性向桶里添加的令牌数量则是桶的最大容量!那么某个时间的瞬间请求过来,服务器的压力是非常大的.

所以此处增加令牌数可以设置的稍微合理些,哪怕间隔时间再长!

以上就是redis lua限流算法实现示例的详细内容,更多关于redis lua限流算法的资料请关注易知道(ezd.cc)其它相关文章!

推荐阅读

    电脑十进制算法|十进制的算法教程

    电脑十进制算法|十进制的算法教程,,十进制的算法教程0x10就是十六进制数10,转换为十进制数是16,即10(十六进制) = 16(十进制)。十六进制转换

    伪代码描述算法

    伪代码描述算法,算法,描述,伪代码,自然语言,语言,编程语言,  伪代码是自然语言和类编程语言组成的混合结构。它比自然语言更精确,描述算法很简

    如何使用PHP实现网站计数器

    如何使用PHP实现网站计数器,网站,次数,计数器,显示,数据库,脚本,在网站设计中,计数器是一个十分实用的功能,可以帮助网站管理员了解网站流量的情

    进程调度详细总结|进程调度算法模拟

    进程调度详细总结|进程调度算法模拟,进程,优先级,一、概念: 无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它

    电信抖音无限流量卡怎么申请办理

    电信抖音无限流量卡怎么申请办理,流量,全国,电信抖音无限流量卡怎么申请办理Douyin无限交通卡是中国电信共同推出的数字卡产品,电信卡有什

    路由算法区分管理距离和最大跳数

    路由算法区分管理距离和最大跳数,路由,网络,路由器,路由协议,协议,状态,管理距离就是人为指定的一个数字,由这个数字来代表路由协议的优先度,数字

    计数器设置|计数器设置说明书

    计数器设置|计数器设置说明书,,计数器设置说明书1、可作计数器、计米器、长度计、码表使用2、按键设定仪表参数,5、6位双排LED数码管显示3