SpringBoot之Redis(五)——使用Lua 脚本
在Redis中有两种运行Lua的方法, 一种是直接发送Lua到Redis服务器去执行,另一种是先把Lua 发送给Redis,Redis会对Lua脚本进行缓存,然后返回一个SHA1的32位编码回来,之后只需要发送SHA1 和相关参数给Redis便可以执行了。这里需要解释的是为什么会存在通过32位编码执行的方法。如果Lua脚本很长,那么就需要通过网络传递脚本给Redis去执行了,而现实的情况是网络的传递速度往往跟不上Redis的执行速度,所以网络就会成为Redis执行的瓶颈。如果只是传递32位编码和参数,那么需要传递的消息就少了许多,这样就可以极大地减少网络传输的内容,从而提高系统的性能。
1. 简易Lua 脚本
采用RedisScript 接口执行一个十分简单的Lua 脚本,这个脚本只是简单地返回一个字符串“Hello Redis”,代码如下:
@RequestMapping("/test1")
public Map<String, Object> test1() {
DefaultRedisScript<String> rs = new DefaultRedisScript<String>();
//设置脚本
rs.setScriptText("return 'Hello Redis' ");
//定义返回类型。注意如果没有这个定义,spring不会返回结果
rs.setResultType(String.class);
RedisSerializer<String> stringRedisSerializer = redisTemplate.getStringSerializer();
String str = (String)redisTemplate.execute(rs,stringRedisSerializer,stringRedisSerializer,null);
Map<String, Object> map = new HashMap<String, Object>();
map.put("str", str);
return map;
}
2. 带有参数的Lua
判断两个字符串是否相同,lua脚本如下:
redis.call ('set', KEYS[1], ARGV[1])
redis.call ('set', KEYS[2], ARGV[2])
local str1 = redis.call ('get', KEYS [1])
local str2 = redis.call ('get', KEYS [2])
if str1 == str2 then
return 1
end
return 0
java实现代码如下:
@RequestMapping("/test2")
public Map<String, Object> test2(String key1, String key2,
String value1, String value2) {
//定义lua脚本:判断两个字符串是否相同
/*
redis.call ('set', KEYS[1], ARGV[1])
redis.call ('set', KEYS[2], ARGV[2])
local str1 = redis.call ('get', KEYS [1])
local str2 = redis.call ('get', KEYS [2])
if str1 == str2 then
return 1
end
return 0
*/
//注意脚本中KYS[l]和KYS[2] 的写法,它们代表客户端传递的第一个键和第二个键,
//而ARGV[l]和ARGV[2]则表示客户端传递的第一个和第二个参数
String lua = "redis.call ('set', KEYS[1], ARGV[1]) \n"
+ "redis.call ('set', KEYS[2], ARGV[2]) \n "
+ " local str1 = redis.call ('get', KEYS [1]) \n "
+ " local str2 = redis.call ('get', KEYS [2]) \n "
+ " if str1 == str2 then \n "
+ " return 1 \n "
+ " end \n "
+ " return 0 \n ";
System.out.println(lua);
DefaultRedisScript<Long> rs = new DefaultRedisScript<Long>();
//设置脚本
rs.setScriptText(lua);
//定义返回类型。注意如果没有这个定义,spring不会返回结果
rs.setResultType(Long.class);
RedisSerializer<String> stringRedisSerializer = redisTemplate.getStringSerializer();
//定义key
List<String> keyList = new ArrayList<String>();
keyList.add(key1);
keyList.add(key2);
Long restult = (Long)redisTemplate.execute(rs,stringRedisSerializer,
stringRedisSerializer,keyList,value1,value2);
Map<String, Object> map = new HashMap<String, Object>();
map.put("restult", restult);
return map;
}
3. 源码下载
源码下载地址:https://download.youkuaiyun.com/download/huangjun0210/10803402