redis实现简单限流

首先我们给出限流的定义:

1. 限定某个行为在指定时间内被允许的最大次数

2. 限定某个用户的某个行为在指定时间内被允许的最大次数

其实二者差不多,前面一句是限定所有人,后面的是限定了每个用户

 

注意

1. 这里我们讨论的是简单的限流,即“限定某个行为在指定时间内被允许的最大次数”中的最大次数是比较小

2. 数量级在几次,几十次,或者几百次级别的。至于上万级别,甚至百万级别的,暂不讨论,因为如果每个玩家都保存这么大的量,内存膨胀得太严重,那种数量级需要更复杂的漏斗限流法

3. 漏斗限流法的介绍请参见这篇博客,等待中

 

简单限流的实现原理:(以每个用户60秒内最多允许10次点赞为例)

1. 利用redis的zset数据结构,保存每次行为及对应的时间戳

    key:点赞标示+用户ID, score:当前毫秒时间戳, value:当前毫秒时间戳,我们主要使用的是score,所以value无所谓的

2. 检测时先移除超过时间限定的旧记录,也就是使用函数  ZREMRANGEBYSCORE() 移除60秒之前的记录

3. 再使用函数 zcard() 获得该key的元素个数,若少于限定次数即,少于10次,则可以操作;否则不允许操作

注意:由于是多条

 

代码如下(这里仅给出伪代码)

// 是否允许某个行为
// userid		:	玩家id
// actionkey	:	行为
// limittime	:	限定的秒数
// maxcount		:	允许的最大次数
bool isActionAllowed(string userid, string actionkey, int limittime, int maxcount)
{
	// zset的key
	string key = actionkey + userid;

	// 当前毫秒时间戳
	uint64_t nowTime = get_current_time();

	// 管道
	Pipeline pipe = pipelined();
	pipe.multi();
	// 核心:移除(0 - limittime秒之前)的记录
	pipe.zremrangeByScore(key, 0, nowTime - limittime*1000);
	//超时时间(加1秒防时间差)
	pipe.expire(key, limittime+1);
	// 记录的行为个数
	int count = pipe.zcard(key);
	return count <= maxcount;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值