18-SpringBoot之Redis(五)——使用Lua 指令碼
阿新 • • 發佈:2018-11-28
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.csdn.net/download/huangjun0210/10803402