redis 控制用户频次问题

11 天前
 chenfang

redis 如何限制用户频次?

目前的是 tomcat 集群,然后会有多个任务 id,同时需要限制用户 id 频次,比如 每人每天展示 5 次

现在的 redis 结构限制频次会丢一些 (第一个图)

现在要改成精准控制频次,目前我想到的方案是 (第二个图)

这个方案倒是可以满足需求,有两个不足的点

  1. 因为涉及到多个任务 id,就会使用多个 hash,然后导致任务 id 和用户 id(key)过多,这样是不是会占用一倍的 redis 内存空间? 多个相同的用户 id 如何才能让它存一份数据,其他的用指针?

  2. 之前没用过 lua 脚本,这个性能如何?

1893 次点击
所在节点    程序员
22 条回复
gongguowei02
11 天前
为什么不考虑使用 Redis 的 INCR+ EXPIRE 来实现限流功能呢?
admol
11 天前
参考如何设计一个分布式限流器: https://jingling.im/posts/design-a-rate-limiter
ddonano
11 天前
Redisson
chenfang
11 天前
@gongguowei02 是个好方法, 多个用户 id 和任务 id 增加内存占用 这个貌似还是解决不了
chenfang
11 天前
@ddonano 我们就是用的 redisson...
chenfang
11 天前
@admol 我去看看这个文章
airqj
11 天前
@chenfang #4 想知道用户量有多大
gongguowei02
11 天前
@admol 大佬 merge 我的 pr 了,满意
nice2cu
11 天前
你目的是想 获取 map 、map 值变更 这两步做成原子操作吗
lua 脚本应该可以的吧
chenfang
11 天前
@nice2cu 可以变结构

,map 中的 map 如果用 lua 涉及到第二个 map 序列话问题,再有就是 lua 脚本会锁整个 redis 实例

这两点来说 两个 map 嵌套不是一个好的方案,如果要精准限制频次的话
Goooooos
11 天前
key: 用户 id_任务 id_日期

incr key ,incr 如果结果=1 ,就执行 expire 。

lua 脚本都没啥必要
admol
11 天前
@gongguowei02 谢谢,不是大佬,只是老,有问题可以随时提
edward1987
11 天前
hash_{任务 id}_{日期}
key 用户 id
你这个需求不用保存历史记录的吧,每天删一删之前的,根本不用考虑内存问题了
edward1987
11 天前
或者 hash_{用户 id}_{日期}
key 任务 id
这种更推荐,因为大表按理来说更占内存,也满足你 [多个相同的用户 id 如何才能让它存一份数据] 这个需求
chenfang
11 天前
@edward1987 #14 大表按理来说更占内存 能解释一下这个么? 另外什么是大表?
chenfang
11 天前
@Goooooos 目前确实在在考虑如何不用 lua 毕竟我感觉对整体性能有不小的影响
edward1987
11 天前
@chenfang 指的 hash 表,大表就是 key 很多的表,也就是按 任务 id 做表名的表,因为扩容的时候是乘以 2 这样去扩容的,所以会占用更多内存。
archxm
11 天前
分桶如何?根据 id 取模,然后分配到特定服务器来处理。非陪到的服务器,从 redis 取数据。判断频次。单台机器,就好做数据冲突处理了吧
archxm
11 天前
@archxm 单台机器,同样对 id 做取模分桶,用线程池解决。单个线程处理单次请求。
chenfang
11 天前
@archxm #18 忘记说了 现在 redis 是集群的 使用 hash 是需要分桶 如果不是 hash 那就会分到不同的实例了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1088766

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX