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

Posted

技术标签:

【中文标题】redis EVAL 真的是原子的并且是安全的吗?【英文标题】:Is redis EVAL really atomic and crash safe? 【发布时间】:2020-08-06 21:15:12 【问题描述】:

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

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

sequential : lua 脚本像单独在服务器上一样运行,这对我来说没问题 atomic / one shot 写道:我不理解 LUA 脚本。什么时候在 LUA 脚本上调用“EXEC like”?因为使用脚本,您可以根据读取进行条件写入(甚至写入,因为某些写入会返回 NX 函数之类的值)。那么redis如何保证脚本执行全部或全部都不执​​行?如果服务器在脚本中间崩溃会发生什么?使用 redis 无法回滚。

(在第二点上,我对 MULTI/EXEC 没有这个顾虑,因为使用 MULTI/EXEC,您无法根据之前的命令进行写入)

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

【问题讨论】:

【参考方案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 中以使其具有原子性,或者至少具有相同的效果。

【讨论】:

以上是关于redis EVAL 真的是原子的并且是安全的吗?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi中的整数读取是原子的吗?

“safe_eval”真的安全吗?

Redis 是并发安全的吗?你确定?

为什么Redis的操作是原子性的,怎么保证原子性的?

Redis 是并发安全的吗?你确定?

Redis 是并发安全的吗?你确定?