redis EVAL 真的是原子的并且崩溃安全吗?

Daw*_*i67 6 crash lua eval atomic redis

Redis 文档似乎确认 EVAL 脚本也与 MULTI/EXEC 事务类似。

用我个人的话来说,这意味着 LUA 脚本保证了两件事:

  • 顺序:lua脚本就像在服务器上单独运行一样,这对我来说没问题
  • 原子/一击写道:我不明白 LUA 脚本。何时在 LUA 脚本上调用“EXEC like”?因为使用脚本,您可以基于读取进行条件写入(甚至写入,因为某些写入会返回像 NX 函数这样的值)。那么,redis 如何保证脚本要么全部执行,要么不执行?如果服务器在脚本执行过程中崩溃怎么办?redis 无法进行回滚。

(我对第二点不关心 MULTI/EXEC,因为使用 MULTI/EXEC 你不能根据以前的命令进行写入)

(对不起,我的英语基础不好,我是法国人)

Did*_*ear 1

刚刚使用这个非常慢的脚本测试了它:

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

^ 这会将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: ...
Run Code Online (Sandbox Code Playgroud)

因此,我随后测试在执行脚本时完全关闭容器以模拟崩溃。

重启后,hellotest键为nil,表示调用的命令实际上都没有被执行。因此,正如文档所述,脚本确实是原子的并且是安全的。

我的信念是,Redis 将 Lua 脚本包装在 a 中,MULTI/EXEC使它们成为原子的,或者至少具有相同的效果。