18-SpringBoot之Redis(五)——使用Lua 脚本

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangjun0210/article/details/84397470

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

猜你喜欢

转载自blog.csdn.net/huangjun0210/article/details/84397470
今日推荐