Redis使用Lua脚本时为什么能保证原子性

昨天面试问了一道题,让我猝不及防,说到了Lua脚本,然后面试官问我Redis使用Lua脚本为什么能保证原子性?
看一看下官方的说明:
“Atomicity of scripts
Redis uses the same Lua interpreter to run all the commands. Also Redis guarantees that a script is executed in an atomic way: no other script or Redis command will be executed while a script is being executed. This semantic is similar to the one of MULTI / EXEC. From the point of view of all the other clients the effects of a script are either still not visible or already completed.”
大致是说:脚本的原子性。
Redis使用(支持)相同的Lua解释器,来运行所有的命令。Redis还保证脚本以原子方式执行:在执行脚本时,不会执行其他脚本或Redis命令。这个语义类似于MULTI(开启事务)/EXEC(触发事务,一并执行事务中的所有命令)。从所有其他客户端的角度来看,脚本的效果要么仍然不可见,要么已经完成。
注意:如果Lua执行出错,可能就会出现一部分命令执行,一部分没有执行。测试如下:
采用的redis版本为:5.0.7
准备数据:

127.0.0.1:6379> set HelloWorld HelloWorld
OK
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> set key2 2
OK

执行一段中间调用redis.call()会出错的Lua脚本,错误原因HelloWorld的key类型是字符串,执行HGET命令会出错的:

127.0.0.1:6379> eval "redis.call('SET',KEYS[1],ARGV[1]);redis.call('HGET','HelloWorld',ARGV[1]);redis.call('SET',KEYS[2],ARGV[2]);return 1;" 2 key1 key2 11 22
(error) ERR Error running script (call to f_cf874476bb7116d92b3b0cbbf8b399ba853907d4): @user_script:1: WRONGTYPE Operation against a key holding the wrong kind of value 
127.0.0.1:6379> get key1
"11"
127.0.0.1:6379> get key2
"2"
127.0.0.1:6379> get HelloWorld
"HelloWorld"
127.0.0.1:6379> 

可以看到key1被设置成了11,但是key2没有变成22,因为中间一步redis.call(‘HGET’,‘HelloWorld’,ARGV[1]);出错中断了脚本的执行。

redis.pcall()函数不会中断Lua脚本的执行,比如接着上面执行脚本:

127.0.0.1:6379> eval "redis.pcall('SET',KEYS[1],ARGV[1]);redis.pcall('HGET','HelloWorld',ARGV[1]);redis.pcall('SET',KEYS[2],ARGV[2]);return 1;" 2 key1 key2 1 22
(integer) 1
127.0.0.1:6379> get HelloWorld
"HelloWorld"
127.0.0.1:6379> get key1
"1"
127.0.0.1:6379> get key2
"22"
127.0.0.1:6379> 

所以为了保证脚本的原子性,要谨慎使用redis.call()函数,如使用一定要确保这个函数的正确性。

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迷梦星河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值