高频面试Redis之签到、限流

1、简介

面试环节,面试官往往会结合一些实际的场景,下面通过分析redis的签到、限流两个最常见的场景。

2、签到

位图,本质string,可理解为byte数组,利用 0、1 标识是否签到。节约内存空间(46字节365天)

// 按月签到 setbit key offset(偏移量,0:1号,1:2号) value(1:签到;0:未签到)
setbit u:sign:1000:202101 0 1  // 1月1号签到 
setbit u:sign:1000:202101 1 1  // 1月2号签到 

bitcount u:sign:1000:202101    // 统计1月份签到总次数
3、滑动窗口限流

假设1分钟内,限定访问60次。使用zset的score值维护一个时间窗口,对于每次新的请求时间窗口都向前滑动一下,然后判断窗口中的元素个数,如果大于60个,则不能访问业务。member字段必须保证唯一性,可以考虑使用时间戳。

// period 时间周期,例如 60秒
// maxCount 时间周期内最大请求数
public boolean isActionAllowed(String userId, String actionKey, int period, int maxCount) {
    String key = String.format("hist:%s:%s", userId, actionKey);
    long now = System.currentTimeMillis();
    Jedis jedis = jedisPool.getResource();
    jedis.zadd(key, now, now + "");
    // 维护窗口,清理窗口外的数据
    // zremrangeByScore --> 移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。
    jedis.zremrangeByScore(key, 0, now - period * 1000);
    Long count = jedis.zcard(key);
    jedis.expire(key, period + 1);
    return count <= maxCount;
}
3、漏斗限流

借助 redis-cell(Redis 4.0) 模块的 cl.throttle 指令实现。

// 参数解释 
// 15 capacity 代表漏洞容量
// 30 60 组合选项,代表漏水速率  oprations / seconds
// 该表达式代表了,漏斗初始容量为 15,即默认可以请求15次;之后受漏斗漏水速率影响,60秒内只能请求30次
cl.throttle liyanchao:reply 15 30 60
4、Lua脚本限流

Lua脚本结合incr命令:

// 10秒内访问3次
-- ./redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3
-- 通过逗号来分割key和arg,注意,这个逗号必须前后要有空格

-- rate.limitingl + 1
local times = redis.call('incr',keyS[1])

-- 第一次访问的时候加上过期时间10秒(10秒过后从新计数)
if times == 1 then
    redis.call('expire',keyS[1], ARGV[1])
end

-- 注意,从redis进来的默认为字符串,lua同种数据类型只能和同种数据类型比较
if times > tonumber(ARGV[2]) then
    return 0
end
return 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲来也无事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值