• springboot使用redisTemplate操作lua脚本


    写在前面

    操作redis使用Lua脚本有诸多好处

    • 减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延和请求次数。
    • 原子性的操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
    • 代码复用:客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本来完成相同的逻辑。
    • 速度快:见 与其它语言的性能比较, 还有一个 JIT编译器可以显著地提高多数任务的性能; 对于那些仍然对性能不满意的人, 可以把关键部分使用C实现, 然后与其集成, 这样还可以享受其它方面的好处。**
    • 可以移植:只要是有ANSI C 编译器的平台都可以编译,你可以看到它可以在几乎所有的平台上运行:从 Windows 到Linux,同样Mac平台也没问题, 再到移动平台、游戏主机,甚至浏览器也可以完美使用 (翻译成JavaScript)。
    • 源码小巧:20000行C代码,可以编译进182K的可执行文件,加载快,运行快。

    使用lua

    @Test
    public void redisLuaTest(){
    
    	String script1 = "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then redis.call('set', KEYS[2], ARGV[2]) return 1 else return 0 end";
    	Long result1 = (Long)redisTemplate.execute(
    			new DefaultRedisScript<Long>(script1, Long.class),
    			Arrays.asList("key1", "key2"),
    			"value1", "value2"
    	);
    	System.out.println(result1); // 1
    
    	// 如果key1==value1,则删除key1,返回删除的状态,否则返回0
    	String script2 = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    	Long result2 = (Long)redisTemplate.execute(
    			new DefaultRedisScript<Long>(script2, Long.class),
    			Arrays.asList("key1"),
    			"value1"
    	);
    	System.out.println(result2); // 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    解释

    /**
    第一个参数使用默认的DefaultRedisScript即可;
    List keys是key的集合
    Object... args是val的集合
    */
    @Override
    public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) {
    	return scriptExecutor.execute(script, keys, args);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    key的集合,在lua中可以使用KEYS[1]、KEYS[2]……获取,注意KEYS必须大写不能拼错;
    val的集合,在lua中可以使用ARGV[1]、ARGV[2]……获取,注意ARGV必须大写不能拼错。

    说白了,使用redisTemplate操作lua,也就是传key的集合和val的集合,这一串lua脚本可以保证其原子性的。

    具体lua语法其实也很简单,基本掌握了if else、循环、赋值语句,就能应付大部分操作redis的命令。

    lua中的redis.call命令就是操作redis的命令,第一个参数就是redis的原始命令,后面的参数就是redis命令的参数,使用起来也非常方便。

  • 相关阅读:
    【Oracle数据库系列笔记】单行函数
    Unigram,Bigram,N-gram介绍
    基于自适应Sigmoid型函数的内镜图像增强与空间变颜色再现方法
    Ps:PSDT 模板文件
    Jenkins学习笔记2
    基于java+SpringBoot+HTML+Mysql)疫情防控微信小程序
    Windows内核--CreateProcess到内核NtCreateProcess(2.3)
    【带限制的完全背包】Educational Codeforces Round 133 (Rated for Div. 2) D. Chip Move
    【从零开始学习 SystemVerilog】4.2、SystemVerilog 进程—— disable fork join
    Unity中RampTex介绍和应用: 溶解特效优化
  • 原文地址:https://blog.csdn.net/A_art_xiang/article/details/126359304