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: ...
然后我测试了在脚本执行时完全关闭容器以模拟崩溃。
重启后,hello
和test
键为nil
,表示调用的命令都没有实际执行。因此,正如文档所述,脚本确实是原子的并且是安全的。
我认为 Redis 将 Lua 脚本包装在 MULTI/EXEC
中以使其具有原子性,或者至少具有相同的效果。
【讨论】:
以上是关于redis EVAL 真的是原子的并且是安全的吗?的主要内容,如果未能解决你的问题,请参考以下文章