gpt4 book ai didi

redis - 有没有更灵活地使用 redis.expire 的选项?

转载 作者:可可西里 更新时间:2023-11-01 11:00:51 25 4
gpt4 key购买 nike

我有一个简单的问题,

假设如果服务器在 10 分钟内收到 10 条来自用户的消息,服务器将发送一封推送邮件。

一开始觉得用redis很简单,

incr("foo"), expire("foo",60*10)

在 Java 中,像下面这样处理出现次数

if(jedis.get("foo")>=10){sendEmail();jedis.del("foo");}

但想象一下,如果用户在第一分钟发送一条消息并在第 10 分钟发送 8 条消息。

key 过期,用户在下一分钟内再次发送 3 条消息。

redis key 将再次创建值为 3,即使用户实际上在 2 分钟内发送了 11 条消息,也不会触发 sendEmail()。

我们将使用 Redis,我们不想将接收时间值放入 Redis。

有什么解决办法吗?

最佳答案

因此,有两种方法可以解决此问题——一种优化空间,另一种优化速度(尽管实际上速度差异应该很小)。

空间优化:

最多保留 9 个不同的计数器; foo1 ... foo9。基本上,在我们向用户发送电子邮件之前,我们将为最多可能的 9 条不同消息中的每一条保留一个计数器,并让每条消息在达到 10 分钟标记时过期。这将像循环队列一样工作。现在执行此操作(为简单起见,在 Python 中,假设我们有一个名为 r 的 Redis 连接):

new_created = False
for i in xrange(1,10):
var_name = 'foo%d' % i
if not (new_created or r.exists(var_name)):
r.set(var_name, 0)
r.expire(var_name, 600)
new_created = True
if not r.exists(var_name): continue
r.incr(var_name, 1)
if r.get(var_name) >= 10:
send_email(user)
r.del(var_name)

如果您采用这种方法,将上述逻辑放在 Lua 脚本中而不是示例 Python 中,它应该会非常快。由于每个用户最多可以存储 9 个计数器,因此它也非常节省空间。

优化速度:

为每个用户保留一个 Redis Sortet Set。每次用户发送消息时,将等于时间戳的键和任意值添加到他的排序集中。然后只需执行 ZCOUNT(now, now - 10 minutes) 并在大于 10 时发送电子邮件。然后 ZREMRANGEBYSCORE(now - 10 minutes, inf)。我知道你说过你不想在 Redis 中保留时间戳,但我认为这是一个更好的解决方案,无论如何你都必须在某个地方保留时间戳的一些变体。

我个人会选择后一种方法,因为空间差异可能不是那么大,并且代码可以在纯 Redis 中快速完成,但这取决于您。

关于redis - 有没有更灵活地使用 redis.expire 的选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23192926/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com