IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> lua redis执行lua脚本 -> 正文阅读

[大数据]lua redis执行lua脚本


lua redis执行lua脚本

???????????

redis使用命令行、redis-cli客户端、redisTemplate执行lua脚本

???????

??????????????

????????????????????????????????????

命令行、客户端执行脚本

?????????

语法格式

# 直接执行脚本(redis-cli客户端执行)
eval lua-script key-num [key key2 key3 ...] [value value2 value3 ...] 


# 缓存脚本后执行(命令行执行,没有进入客户端)
redis-cli --eval --lua-script [key key2 ...] , [value value2 ...]
 * key与value用逗号间隔,且逗号前后有空格)

??????????

lua 调用redis命令

redis.call(command, KEYS[1], KEYS[2], ... , ARGV[1], ARGV[2], ...)

# 命令说明
KEYS[1]:第一个key
ARGV[1]:第一个value
KEYS、ARGV不需要一一对应,个数不需要相等

# 示例
redis.call('set', KEYS[1], ARGV[1])
redis.call('get', KEYS[1])

??????????

示例:redis-cli客户端执行脚本

huli@hudeMacBook-Pro ~ % docker exec -it redis2 bash

-- redis-cli客户端
root@0d79dbff702e:/data# redis-cli

-- KEYS、ARGV名称是固定的,不能随便设置
127.0.0.1:6379> eval "redis.call('set',key[1],arg[1])" 1 set 瓜田李下
(error) ERR Error running script (call to f_c7f25ef16dd21c6a4dc44cf3964041227459f25e): @enable_strict_lua:15: user_script:1: Script attempted to access nonexistent global variable 'key'

-- set key=瓜田李下
127.0.0.1:6379> eval "redis.call('set',KEYS[1],ARGV[1])" 1 key 瓜田李下
(nil)

-- 获取key:没有return,无返回值
127.0.0.1:6379> eval "redis.call('get',KEYS[1])" 1 key
(nil)

-- 调用return,返回key对用的value(瓜田李下)
-- 由于是中文,redis存储的时候进行了序列化
127.0.0.1:6379> eval "return redis.call('get',KEYS[1])" 1 key
"\xe7\x93\x9c\xe7\x94\xb0\xe6\x9d\x8e\xe4\xb8\x8b"

-- 设置key2=gtlx
127.0.0.1:6379> eval "redis.call('set',KEYS[1],ARGV[1])" 1 key2 gtlx
(nil)

-- 返回key2对应的value(瓜田李下)
127.0.0.1:6379> eval "return redis.call('get',KEYS[1])" 1 key2
"gtlx"

???????????

示例:命令行执行脚本文件

huli@hudeMacBook-Pro ~ % docker exec -it redis2 bash

-- redis命令行生成脚本文件:test.lua
root@0d79dbff702e:/data# echo "redis.call('set', KEYS[1], ARGV[1]) return redis.call('get',KEYS[1])" > test.lua

-- 查看文件
root@0d79dbff702e:/data# ls
dump.rdb  test.lua
root@0d79dbff702e:/data# cat test.lua
redis.call('set', KEYS[1], ARGV[1]) return redis.call('get',KEYS[1])

-- 命令行执行文件
root@0d79dbff702e:/data# redis-cli --eval test.lua key , gtlx
"gtlx"

??????????

????????????

????????????????????????????????????

redisTemplate 执行脚本

?????????

***********

相关类与接口

???????

RedisScript

public interface RedisScript<T> {
    String getSha1();

    @Nullable
    Class<T> getResultType();

    String getScriptAsString();

    default boolean returnsRawValue() {
        return this.getResultType() == null;
    }

    static <T> RedisScript<T> of(String script) {
        return new DefaultRedisScript(script);
    }

    static <T> RedisScript<T> of(String script, Class<T> resultType) {
        Assert.notNull(script, "Script must not be null!");
        Assert.notNull(resultType, "ResultType must not be null!");
        return new DefaultRedisScript(script, resultType);
    }

    static <T> RedisScript<T> of(Resource resource) {
        Assert.notNull(resource, "Resource must not be null!");
        DefaultRedisScript<T> script = new DefaultRedisScript();
        script.setLocation(resource);
        return script;
    }

    static <T> RedisScript<T> of(Resource resource, Class<T> resultType) {
        Assert.notNull(resource, "Resource must not be null!");
        Assert.notNull(resultType, "ResultType must not be null!");
        DefaultRedisScript<T> script = new DefaultRedisScript();
        script.setResultType(resultType);
        script.setLocation(resource);
        return script;
    }
}

???????

DefaultRedisScript

public class DefaultRedisScript<T> implements RedisScript<T>, InitializingBean {
    private final Object shaModifiedMonitor;
    @Nullable
    private ScriptSource scriptSource;
    @Nullable
    private String sha1;
    @Nullable
    private Class<T> resultType;

    public DefaultRedisScript() {
        this.shaModifiedMonitor = new Object();
    }

    public DefaultRedisScript(String script) {
        this(script, (Class)null);
    }

    public DefaultRedisScript(String script, @Nullable Class<T> resultType) {
        this.shaModifiedMonitor = new Object();
        this.setScriptText(script);
        this.resultType = resultType;
    }

    public void afterPropertiesSet() {
        Assert.state(this.scriptSource != null, "Either script, script location, or script source is required");
    }

    public String getSha1() {
        synchronized(this.shaModifiedMonitor) {
            if (this.sha1 == null || this.scriptSource.isModified()) {
                this.sha1 = DigestUtils.sha1DigestAsHex(this.getScriptAsString());
            }

            return this.sha1;
        }
    }

    @Nullable
    public Class<T> getResultType() {
        return this.resultType;
    }

    public String getScriptAsString() {
        try {
            return this.scriptSource.getScriptAsString();
        } catch (IOException var2) {
            throw new ScriptingException("Error reading script text", var2);
        }
    }

    public void setResultType(@Nullable Class<T> resultType) {
        this.resultType = resultType;
    }

    public void setScriptText(String scriptText) {
        this.scriptSource = new StaticScriptSource(scriptText);
    }

    public void setLocation(Resource scriptLocation) {
        this.scriptSource = new ResourceScriptSource(scriptLocation);
    }

    public void setScriptSource(ScriptSource scriptSource) {
        this.scriptSource = scriptSource;
    }
}

?????????

RedisTemplate:stringRedisTemplate继承了redisTemplate,也可执行lua脚本

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {

    public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) {
        return this.scriptExecutor.execute(script, keys, args);
    }

    public <T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSerializer<T> resultSerializer, List<K> keys, Object... args) {
        return this.scriptExecutor.execute(script, argsSerializer, resultSerializer, keys, args);
    }

???????????

***********

示例

???????

test.lua

??????????????????????

redis.call("set",KEYS[1], ARGV[1])
return redis.call("get", KEYS[1])

?????????

RedisLuaTest

@Component
public class RedisLuaTest {

    @Value("classpath:/lua/test.lua")
    private Resource resource;

    @javax.annotation.Resource
    private StringRedisTemplate stringRedisTemplate;

    @PostConstruct
    public void init(){
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        redisScript.setLocation(resource);
        redisScript.setResultType(String.class);

        System.out.println("redisScript.getSha1():"+redisScript.getSha1());
        System.out.println("redisScript.getScriptAsString():"+redisScript.getScriptAsString());

        String value = stringRedisTemplate.execute(redisScript, Collections.singletonList("key"), "瓜田李下");
        System.out.println(value);
    }
}

????????

控制台输出

2022-06-19 19:50:59.094  INFO 886 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
2022-06-19 19:50:59.378  INFO 886 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-06-19 19:50:59.384  INFO 886 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-06-19 19:50:59.385  INFO 886 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.63]
2022-06-19 19:50:59.468  INFO 886 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-06-19 19:50:59.468  INFO 886 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 850 ms
redisScript.getSha1():6c45d62f3875095a03105f73b04c64e77b17fa1e
redisScript.getScriptAsString():redis.call("set",KEYS[1], ARGV[1])
return redis.call("get", KEYS[1])
瓜田李下
2022-06-19 19:51:00.240  INFO 886 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-06-19 19:51:00.249  INFO 886 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 2.043 seconds (JVM running for 2.604)

?????????

?????????????????

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-06-20 23:03:25  更:2022-06-20 23:03:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:59:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码