Redis的EVAL命令真的具有原子性和崩溃安全性吗?

6

Redis文档似乎肯定了EVAL脚本与MULTI/EXEC事务相似。

以我的个人理解,这意味着LUA脚本保证两件事情:

  • 顺序执行:LUA脚本就像单独在服务器上运行一样,这对我来说没问题。
  • 原子性/一次性写入:我不理解LUA脚本如何实现“像EXEC一样”的调用。因为你可以根据读取(甚至写入)执行条件写入的脚本(因为某些写入函数会返回值,例如NX函数)。因此,Redis如何确保脚本要么全部执行,要么都不执行?如果服务器在脚本执行过程中崩溃会发生什么?Redis无法回滚。

(我对于第二个问题不担心MULTI/EXEC事务,因为使用MULTI/EXEC事务不能基于以前的命令进行写入)

(抱歉我的英语很基础,我是法国人)

1个回答

1

我刚刚使用这个非常慢的脚本进行了测试:

eval "redis.call('set', 'hello', 10); for i = 1, 1000000000 do redis.call('set', 'test', i) end" 0

^ 这段代码将 hello 键设置为 10,然后无限期地将 test 键设置为数字。

在执行脚本时,Redis会记录以下警告:

# Lua slow script detected: still in execution after 5194 milliseconds. You can try killing the script using the SCRIPT KILL command. Script SHA1 is: ...

于是我测试了在脚本执行时完全关闭容器以模拟崩溃。

重启后,hellotest键是nil,这意味着没有任何调用的命令实际被执行。因此,脚本确实是原子性的并且具有崩溃安全性,就像文档所述。

我相信Redis将Lua脚本包装在MULTI/EXEC中使其具有原子性,或者至少具有相同的效果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接