redis - redis EVAL 真的是原子的并且是安全的吗?
问题描述
Redis doc 似乎确认 EVAL 脚本也类似于 MULTI/EXEC 事务。
用我个人的话来说,这意味着 LUA 脚本可以保证两件事:
- 顺序:lua 脚本像单独在服务器上一样运行,这对我来说没问题
- atomic / one shot 写道:我不理解 LUA 脚本。什么时候在 LUA 脚本上调用“EXEC like”?因为使用脚本,您可以根据读取进行条件写入(甚至写入,因为某些写入会返回 NX 函数之类的值)。那么 redis 如何保证脚本执行全部或全部执行?如果服务器在脚本中间崩溃会发生什么?redis 无法回滚。
(在第二点上,我对 MULTI/EXEC 没有这个顾虑,因为使用 MULTI/EXEC 你不能根据以前的命令进行写入)
(对不起基本的英语,我是法国人)
解决方案
刚刚使用这个非常慢的脚本对其进行了测试:
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 脚本包装在 aMULTI/EXEC
中以使其具有原子性,或者至少具有相同的效果。
推荐阅读
- swift - 从任何类型转换为字符串崩溃
- qt - 如何在兄弟 QVideoWidget 之上创建一个透明的 QWidget?
- java - 使用多线程在特定时间内更改 javafx 圆圈颜色
- c# - 使用 xpath 时访问了错误的 xml 节点
- android-studio - Android Studio Flutter 插件的颜色选择器在哪里
- c# - System.AccessViolationException:C# .NET 和 C++ 应用程序之间的 shared_ptr
- ios - UIView bounds.applying 但有旋转
- c# - 基于接口实现的 LINQ 连接
- node.js - 减少nodejs内存使用
- xml - 如何使用 xslt 将一个 xml 文件的内容复制到另一个空 xml 文件