首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过远程脚本定期运行tally脚本

通过远程脚本定期运行tally脚本
EN

Stack Overflow用户
提问于 2022-07-29 17:18:40
回答 2查看 59关注 0票数 0

我正在设置一个Redis实例,该实例接收由键/值对组成的数据点,该键可以具有不同类型的前缀。每个键都有一个ttl过期。每隔15分钟,我就计划运行一个lua脚本,它将对带有特定前缀的各种键的值进行统计。这是从运行节点脚本的cron作业中删除的。

代码语言:javascript
复制
local data = redis.call('KEYS', KEYS[1] .. "*")
for i=1,#data do
  local value = 'rollup.' .. KEYS[1] .. redis.call('GET', data[i])
  if redis.call('EXISTS', value)==1 then
    redis.call('INCR', value)
  else
    redis.call('SET', value, 1)
  end
end

节点脚本:

代码语言:javascript
复制
cron.scheduleJob("*/15 * * * *", async () => {
   try {
     await redisServer.eval(fs.readFileSync("./dist/tally.lua"), 0);
   } catch (ex) {
     logger.error("Calling rollup lua failed. " + util.inspect(ex));
   }
 });

我好像收到了这些错误

代码语言:javascript
复制
ReplyError: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

周期性的。这是lua脚本的问题,还是有更好的方法可以运行?也就是说,除了在接收其他常规调用(如set、external和ping )的端口上运行外部lua脚本之外(我还有一个心跳,它每秒钟都会刷新,以确保它是实时的)。我读过Redis有一种安排任务的方法,但是我很难找到这样做的例子。或者也许有一种内置的方式来实现我想要做的事情?

编辑:我的基本问题可能是lua脚本正在原子地运行,即在发生这种情况时,其他任何东西都无法运行,从而导致与Redis的所有其他交互都备份起来。是否有更快的方法来完成一个计数,可能不涉及一个lua脚本,我应该提取数据并在节点脚本中进行计数吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-29 18:53:44

键的使用是一种反模式。

在redis中的任何地方使用Keys命令都被认为是一种真正的反模式,Keys在遍历整个键空间时实际上会阻塞Redis,这需要相当长的时间。

它扼杀了你的剧本

这里发生的是,您的lua脚本超过lua时间限制(默认为5秒),这是redis开始拒绝命令之前的最大允许时间,这是因为阻止lua脚本。

基本上,您运行的是一个糟糕的脚本,它阻止Redis做任何事情。

使用排序集代替

这似乎是最好用排序集来处理的东西。当然,您可以将TTLs保留在您想要过期的密钥上,这很好,但实际上,您可以将TTLs设置为排序集,并将过期时间设为记分,成员作为密钥名。

所以如果你做了一个:

代码语言:javascript
复制
SET foo bar EX 50

从现在开始,您只需计算50秒的UNIX时间戳,并将其用作得分,假设为1659120294,然后将其添加到您的rollup zset:

代码语言:javascript
复制
ZADD zset:rollup 1659120294 foo

然后,当您查询计数时所需要做的就是使用当前时间的计数,假设发生在1659120394:

代码语言:javascript
复制
ZCOUNT zset:rollup 1659120394 inf

,它将显示所有未过期密钥的计数。

最棒的是,当您完成计数时,您可以一次进入并删除排序集中的所有过期密钥,使用ZREMRANGEBYSCORE,假设相同的时间。

代码语言:javascript
复制
ZREMRANGEBYSCORE zsetrollup -inf 1659120394

ZADD和ZCOUNT非常快,它们分别是O(1)和O(log(n)),ZREMRANGE在每次从其中清除的元素数中的O(N)比O(N)慢一些。但是,与每隔15分钟对数据库运行密钥相比,这将是相对较小的。

票数 0
EN

Stack Overflow用户

发布于 2022-07-29 19:22:31

我决定在插入带有ttl的键/值对时,增加计数,而不是使用脚本主动记录数据,订阅键的过期,然后在该键到期时将其减少。加上这个答案,以防有人试图做类似的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73168938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档