前言:
前面我们已经分析了如何实现分布式锁,以及在实现的过程中分布式锁存在的各种问题,并且提出了解决办法,虽然我们上面看似实现了分布式锁,但是却存在一个致命问题,原子性问题,无论是获取锁还是释放锁,都是用多行Redis命令来实现,如果无法保证这个命令执行的原子性,则整个过程中就存在安全问题,在这里我们要引入另一门语言Lua,Lua脚本语言则可以用来解决多行Redis命令原子性问题,下面来看一下Lua脚本语言;
一、Redis中如何执行Lua脚本:
1.EVAL命令:
执行一个脚本包括参数:
script:脚本内容或者脚本地址;
numkeys:脚本中用到的key的数量,接下来的numkeys个数会作为key的参数,剩下的作为arg的参数;
arg:其他参数,会被存入脚本环境中的ARGV数组中,角标从1开始;
示例:EVAL "return 'hello world'" 0,其中
"return 'hello world'":就是脚本的内容,在这里这几返回一个字符串;
0:也就是说没有用到key参数,直接返回
效果:
2、SCRIPT LOAD命令:
将一个脚本编译并且缓存起来,生成一个SHA1值并且返回,为了方便使用,参数script就是脚本内容货地址;
一上面脚本为案例演示:
3、EVALSHA命令:
与EVAL类似,执行一段脚本,区别是通过脚本的sha1值执行,去脚本缓存中查询,然后执行,参数:
sha1:就是脚本对应的sha1值;
示例:
二、Lua脚本的基本语法:
Lua的详细语法可以参考网上的一些网站学习,列如:Lua菜鸟教程,学习任何一门语言都是从基本的如:变量、数据类型、循环、逻辑判断、运算等入手的,Lua的语法与java有很多相似之处,具体的就不一一细说了,在这里只举例一些最基本的用法:
1、声明变量:
-- test.lua 文件脚本 a = 5 -- 全局变量 local b = 5 -- 局部变量
2、打印结果;
> print("Hello World!") Hello World! >
3、条件控制:
if(布尔表达式) then --[ 布尔表达式为 true 时执行该语句块 --] else --[ 布尔表达式为 false 时执行该语句块 --] end
4、循环语句:
while( true ) do print("循环将永远执行下去") end