redis 如何限制用户频次?
目前的是 tomcat 集群,然后会有多个任务 id,同时需要限制用户 id 频次,比如 每人每天展示 5 次
现在的 redis 结构限制频次会丢一些 (第一个图)
现在要改成精准控制频次,目前我想到的方案是 (第二个图)
这个方案倒是可以满足需求,有两个不足的点
因为涉及到多个任务 id,就会使用多个 hash,然后导致任务 id 和用户 id(key)过多,这样是不是会占用一倍的 redis 内存空间? 多个相同的用户 id 如何才能让它存一份数据,其他的用指针?
之前没用过 lua 脚本,这个性能如何?
1
gongguowei02 4 天前 1
为什么不考虑使用 Redis 的 INCR+ EXPIRE 来实现限流功能呢?
|
2
admol 4 天前
参考如何设计一个分布式限流器: https://jingling.im/posts/design-a-rate-limiter
|
3
ddonano 4 天前
Redisson
|
4
chenfang OP @gongguowei02 是个好方法, 多个用户 id 和任务 id 增加内存占用 这个貌似还是解决不了
|
8
gongguowei02 3 天前
@admol 大佬 merge 我的 pr 了,满意
|
9
nice2cu 3 天前
你目的是想 获取 map 、map 值变更 这两步做成原子操作吗
lua 脚本应该可以的吧 |
10
chenfang OP @nice2cu 可以变结构
,map 中的 map 如果用 lua 涉及到第二个 map 序列话问题,再有就是 lua 脚本会锁整个 redis 实例 这两点来说 两个 map 嵌套不是一个好的方案,如果要精准限制频次的话 |
11
Goooooos 3 天前
key: 用户 id_任务 id_日期
incr key ,incr 如果结果=1 ,就执行 expire 。 lua 脚本都没啥必要 |
12
admol 3 天前
@gongguowei02 谢谢,不是大佬,只是老,有问题可以随时提
|
13
edward1987 3 天前
hash_{任务 id}_{日期}
key 用户 id 你这个需求不用保存历史记录的吧,每天删一删之前的,根本不用考虑内存问题了 |
14
edward1987 3 天前
或者 hash_{用户 id}_{日期}
key 任务 id 这种更推荐,因为大表按理来说更占内存,也满足你 [多个相同的用户 id 如何才能让它存一份数据] 这个需求 |
15
chenfang OP @edward1987 #14 大表按理来说更占内存 能解释一下这个么? 另外什么是大表?
|
17
edward1987 3 天前
@chenfang 指的 hash 表,大表就是 key 很多的表,也就是按 任务 id 做表名的表,因为扩容的时候是乘以 2 这样去扩容的,所以会占用更多内存。
|
18
archxm 3 天前
分桶如何?根据 id 取模,然后分配到特定服务器来处理。非陪到的服务器,从 redis 取数据。判断频次。单台机器,就好做数据冲突处理了吧
|
21
archxm 3 天前
@chenfang #20 不管 redis 是啥,你后台服务器几台呢?如果多台,就先按用户 id 分桶,用户肯定每次固定分配到一台服务器。
然后用户分到一台服务器后,你的服务器是多线程或多进程吗?然后你可以在服务器上设置线程池或进程池,来定死用户到固定线程(或进程)上来处理,这样不会发生冲突。不用管具体存到 redis 哪个分片 |
22
ychost 3 天前
疲劳度控制问题是吧,设置好数据过期时间应该费不了多少内存
|