• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

redis 执行lua脚本

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

参考: 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

3. Spring boot 项目跑lua脚本

Springboot 项目跑lua脚本一般基于redisTemplate。

1. pom引入如下依赖:

        <!-- 引入 redis 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. 将上面Test.lua 脚本放到resource/script目录下:

 3. 编写测试方法:

package com.xm.ggn.controller;

import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.http.ResponseEntity;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@Controller
public class TestController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/lua")
    public ResponseEntity lua() {
        List<String> keys = Arrays.asList("testLua", "hello lua");
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/Test.lua")));
        redisScript.setResultType(Boolean.class);
        Boolean execute = stringRedisTemplate.execute(redisScript, keys, "100");
        assert execute != null;
        return ResponseEntity.ok(execute);
    }
}

redisTemlate 最终会调用org.springframework.data.redis.core.script.DefaultScriptExecutor#execute(org.springframework.data.redis.core.script.RedisScript<T>, java.util.List<K>, java.lang.Object...) 方法

4. 访问测试:

curl http://localhost:8088/lua

补充: 也可直接用字符串构造对象

例如:

    @GetMapping("/lua")
    public ResponseEntity lua() {
        List<String> keys = Arrays.asList("testLua", "hello lua");
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>("local key = KEYS[1]; local val = KEYS[2]; local expire = ARGV[1]; redis.call(\"set\", key, val); redis.call(\"expire\", key, expire);");
        redisScript.setResultType(Boolean.class);
        Boolean execute = stringRedisTemplate.execute(redisScript, keys, "100");
        assert execute != null;
        return ResponseEntity.ok(execute);
    }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
lua调用C模块过程记录发布时间:2022-07-22
下一篇:
Lua了解&amp;为什么游戏开发用Lua发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap