部分摘自:https://blog.csdn.net/yzf279533105/article/details/111310685
仅做个人备份,浏览请看原文
目录
令牌桶算法 概念
令牌桶算法的优势:令牌桶在应对突发流量的时候,桶内假如有 100 个令牌,那么这 100 个令牌可以马上被取走,而不像漏桶那样匀速的消费。所以在应对突发流量的时候令牌桶表现的更佳。
详见:https://blog.csdn.net/chushoufengli/article/details/114978259
安装
(由于redis-cell是使用rust语言编写的,而本人对rust毫无研究,也不想去部署rust的环境,所以直接下载编译好的动态库so文件,不再源码编译)
1.打开地址:https://github.com/brandur/redis-cell/releases,挑选适合自己环境的压缩包,下载最新的,本人是ubuntu环境,下载linux版的即可,下载到/usr/local/redis/redis-stable目录,并解压
2. 修改要使用的redis.conf文件,添加一行 “loadmodule /usr/local/redis/redis-stable/libredis_cell.so”,保存后,重启redis即可
3. 连接进我们的redis,运行命令 module list ,可以查看目前已经启用的module
使用
如上面简言所述,redis-cell使用很简单,只有一个命令
命令格式:cl.throttle key名字 令牌桶容量-1 令牌产生个数 令牌产生时间 本次取走的令牌数 (不写时默认1,负值表放入令牌)
返回格式:0成功,1失败
令牌桶的容量
当前桶内剩余的令牌数
成功时该值为-1,失败时表还需要等待多少秒可以有足够的令牌
表预计多少秒后令牌桶会满
示例1(key:mybag,该key不存在时会新建,容量为100(也就是99+1=100), 每10秒产生1个令牌,本次取出40个)
127.0.0.1:6379> cl.throttle mybag 99 1 10 40
1) (integer) 0
2) (integer) 100
3) (integer) 60
4) (integer) -1
5) (integer) 400
0表示取出成功,100表令牌桶容量,60表桶内剩余令牌数,-1表成功即本次取令牌不需等待,400表预计还需要400秒令牌桶会满,根据我们的速度设定,每10秒产生一个令牌,确实是需要400秒
示例2(从mybag的令牌桶中再取出40个)
127.0.0.1:6379> cl.throttle mybag 99 1 10 40
1) (integer) 0
2) (integer) 100
3) (integer) 20
4) (integer) -1
5) (integer) 798
127.0.0.1:6379> cl.throttle mybag 99 1 10 40
1) (integer) 1
2) (integer) 100
3) (integer) 20
4) (integer) 196
5) (integer) 796
第一次的0表示取出成功,100表令牌桶容量,20表桶内剩余令牌数,-1表成功即本次取令牌不需等待,798表预计还需要798秒令牌桶会满
第二次的1表示取出失败,100表令牌桶容量,20表桶内剩余令牌数,196表失败,还需要等待196秒可以重试本次操作,796表预计还需要796秒令牌桶会满
示例3(往mybag的令牌桶中先放入40个,再取出40个)
127.0.0.1:6379> cl.throttle mybag 99 1 10 -40
1) (integer) 0
2) (integer) 100
3) (integer) 126
4) (integer) -1
5) (integer) -262
127.0.0.1:6379> cl.throttle mybag 99 1 10 40
1) (integer) 0
2) (integer) 100
3) (integer) 60
4) (integer) -1
5) (integer) 400
放入40个时,0表放入成功,126就没啥意义了,因为最大容量才100,当然桶内不可能有126个;-262更诡异了,桶满了就满了呗,干嘛告诉我需要负262秒呢,感觉桶满时0更准确
我们验证前面的猜想,马上再取出40个可以看到结果值0表成功,60表桶内还剩下60个令牌,即容量100减去本次的40得到,也就验证了第一次返回的126毫无意义