参考: https://redis.io/commands/eval
参考:https://redis.io/topics/ldb
1. redis-cli 命令行测试
命令如下:key 可以理解用于传键名称,而arg 用于传递其他参数
EVAL script numkeys key [key ...] arg [arg ...]
1. 例如
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first"
简单理解: 2 是key的个数,接下来key1、key2是key;剩下的first、second是arg参数列表
2. 放入值然后获取值
存值:
127.0.0.1:6379> eval "return redis.call('set','foo','bar')" 0 OK
取值:
127.0.0.1:6379> eval "return redis.call('get','foo')" 0 "bar"
2. redis-cli 加脚本测试lua 脚本
官网解释:Starting with version 3.2 Redis includes a complete Lua debugger, that can be used in order to make the task of writing complex Redis scripts much simpler.
其命令如下:(多个key和arg用逗号隔开即可)
./redis-cli --ldb --eval /tmp/script.lua mykey somekey , arg1 arg2
例如:
1. 创建脚本:Test.lua, 内容如下:
--- 获取key local key = KEYS[1] --- 获取value local val = KEYS[2] --- 获取一个参数 local expire = ARGV[1] --- 如果redis找不到这个key就去插入 if redis.call("get", key) == false then --- 如果插入成功,就去设置过期值 if redis.call("set", key, val) then --- 由于lua脚本接收到参数都会转为String,所以要转成数字类型才能比较 if tonumber(expire) > 0 then --- 设置过期时间 redis.call("expire", key, expire) end return true end return false else return false end
2. 命令行测试脚本:
(1) 测试部加--ldb执行命令,相当于用redis-cli 跑lua脚本
liqiang@root MINGW64 ~/Desktop/新建文件夹
$ redis-cli.exe --eval Test.lua testKey testValue , 100 1
(2) 可以调试lua脚本:
redis-cli.exe --ldb --eval Test.lua testKey testValue , 100
来源:https://www.cnblogs.com/qlqwjy/p/14532561.html
lua基础教程:https://blog.csdn.net/weixin_41158378/article/details/112793673
1、使用RedisTemplate执行lua脚本:
public void redisAddScriptExec(){ /** * List设置lua的KEYS */ List<String> keyList = new ArrayList(); keyList.add("count"); keyList.add("rate.limiting:127.0.0.1"); /** * 用Mpa设置Lua的ARGV[1] */ Map<String,Object> argvMap = new HashMap<String,Object>(); argvMap.put("expire",10000); argvMap.put("times",10); /** * 调用脚本并执行 */ List result = redisTemplate1.execute(getRedisScript,keyList, argvMap); System.out.println(result); }
2、lua脚本
--获取KEY local key1 = KEYS[1] local key2 = KEYS[2] -- 获取ARGV[1],这里对应到应用端是一个List<Map>. -- 注意,这里接收到是的字符串,所以需要用csjon库解码成table类型 local receive_arg_json = cjson.decode(ARGV[1]) --返回的变量 local result = {} --打印日志到reids --注意,这里的打印日志级别,需要和redis.conf配置文件中的日志设置级别一致才行 redis.log(redis.LOG_DEBUG,key1) redis.log(redis.LOG_DEBUG,key2) redis.log(redis.LOG_DEBUG, ARGV[1],#ARGV[1]) --获取ARGV内的参数并打印 local expire = receive_arg_json.expire local times = receive_arg_json.times redis.log(redis.LOG_DEBUG,tostring(times)) redis.log(redis.LOG_DEBUG,tostring(expire)) --往redis设置值 redis.call("set",key1,times) redis.call("incr",key2) redis.call("expire",key2,expire) --用一个临时变量来存放json,json是要放入要返回的数组中的 local jsonRedisTemp={} jsonRedisTemp[key1] = redis.call("get",key1) jsonRedisTemp[key2] = redis.call("get", key2) jsonRedisTemp["ttl"] = redis.call("ttl",key2) redis.log(redis.LOG_DEBUG, cjson.encode(jsonRedisTemp)) result[1] = cjson.encode(jsonRedisTemp) --springboot redistemplate接收的是List,如果返回的数组内容是json对象,需要将json对象转成字符串,客户端才能接收 result[2] = ARGV[1] --将源参数内容一起返回 redis.log(redis.LOG_DEBUG,cjson.encode(result)) --打印返回的数组结果,这里返回需要以字符返回 return result
3、设置日志级别
代码中,redis.log()函数向运日志中输出信息,这里要注意一下,函数里面设置的日志级别要和redis.conf配置文件中设置的日志级别一样才能正常打印到文件,这里我是设置成了deubg级别。这里可设置的级别有4种,分别如下:
redis.LOG_DEBUG
redis.LOG_VERBOSE
redis.LOG_NOTICE
redis.LOG_WARNING
在应用端,我们设置接收返回的数据类型是List,所以在Lua脚本中,返回的类型用table与之对应,并且放到table变量中的内容,得是字符串,应用端才能通过反序列化,正常解析。