lua脚本
一种轻量级的脚本语言
Redis+lua
通过在redis中使用lua脚本可以实现复杂的操作
lua脚本在redis中的执行是原子性的
lua脚本
lua
local ret = redis.call('hset', KEYS[1], ARGV[1], ARGV[2], ARGV[3], ARGV[4]);
redis.call('incr', KEYS[2]);
return ret..'';
KEYS:表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,KEYS[1]表示第一个key,KEYS[2]表示第2个key,依次类推。
ARGV:表示在脚本中所用到的参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类),ARGV[1]表示第一个参数,ARGV[2]表示第二个参数,依次类推。
redis执行lua脚本
使用EVAL命令执行lua脚本
eval 保证了redis的命令本身具有原子性并且整个脚本的执行具有原子性
lua
EVAL script numkeys key [key ...] arg [arg ...]
script**: 是一段 Lua 5.1 脚本程序。**
numkeys: 用于指定键名参数的个数。
key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
Java项目集成lua脚本
使用redisTemplate.execute()方法
java
<T> T execute(RedisScript<T> script, List<K> keys, Object... args)
使用RedisScript的实现类DefaultRedisScript
将lua脚本的内容传入对象并指定返回值类型
java
public DefaultRedisScript(String script, @Nullable Class<T> resultType) {
this.shaModifiedMonitor = new Object();
this.setScriptText(script);
this.resultType = resultType;
}
或者直接指定lua脚本的位置
java
public void setScriptSource(ScriptSource scriptSource) {
this.scriptSource = scriptSource;
}
@Bean("Lua_test01")
public DefaultRedisScript<Integer> getLuaTest01() {
DefaultRedisScript<Integer> redisScript = new DefaultRedisScript<>();
//resource目录下的scripts文件下的Lua_test01.Lua文件
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("scripts/Lua_test01.Lua")));
redisScript.setResultType(Integer.class);
return redisScript;
}
lua脚本的注意事项
在redis集群中执行lua脚本必须保证多个key落在同一个节点下(通过{}+分片集群保证),否则会报错