1. 程式人生 > >18-SpringBoot之Redis(五)——使用Lua 指令碼

18-SpringBoot之Redis(五)——使用Lua 指令碼

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