如何使用Redis执行Lua脚本

为什么要使用Lua脚本?

lua脚本有很多的优点,但是对于我来说我使用它只因为它能保证原子性。为什么它能保证原子性你就使用它呢?一个简单的例子,在我们的Java代码中,一个简单的++i都不能保证原子性更别提复杂的情况了。但是使用lua在执行几百行代码的情况下都不需要考虑高并发所带来的问题。

lua基础

  1. 创建lua脚本 就像创建其他的文件一样,新建一个以.lua为后缀的文件,比如说test.lua
  2. –单行注释。–[[多行注释,多行注释–]]
  3. 打印语句
print("Hello World!")
  1. 常见数据类型 boolean、number、string、nil(这个就是我们平常见的null) 一些小的细节问题 · type() 用于查看变量的数据类型,比如print(type(10.4*3)) --> number · 判断一个变量是否为空时应该使用" a"==“nil"而不是” a"==nil · lua中"1"+“1” 不是合并字符串成ab而是等于2,想要进行字符串拼接需要"1"…“1” -->11 · lua查看字符串长度应该这样来print(#“Hello”) -->5 · lua中比较不等于的时候要这样比较:a~= b · lua中逻辑运算符是and、or、not
  2. 变量
a = 5               -- 全局变量local b = 5         -- 局部变量
  1. 条件判断
if maxValue > limit then          value = limit;      else if          value = maxValue;      else           value = 0;      end
  1. 循环
for i, v in ipairs(a) do    print(i, v)      --i是索引,且是从1开始的。v就是value了。end
  1. 函数
function test(n)    if n == 0 then        return 1    else        return -1    endend

看完以上几条你的基础其实已经过关了,如果仅仅在操作redis上的话就已经够了。

redis执行lua脚本

  1. 在脚本中如何与redis进行交互
local value = redis.call('GET',key);redis.call('SET',key,value+2);redis.call('DECR',key);redis.call('EXPIRE',key,10);

你是否看明白了呢,只需要执行redis.call命令,第一个参数放入要执行的命令,后面的参数放入命令需要的参数就ok了。

  1. 如何执行脚本呢
redis-cli --eval redis-ratelimiter-counter.lua key limit , value1 value2

上方这段命令的意思呢,其实就是告诉redis:请你启动客户端的时候帮我执行一下redis-ratelimiter-counter.lua这个文件,然后呢,执行文件的话有这么几个参数,key、limit 、 value1、value2 细心小伙伴可能会有疑问了,为什么传了4个参数只有一个逗号其他都是空格隔开呢。我们来看一下他们分别是怎么获取的就明白了

local key = KEYS[1];local limit = KEYS[2];
local value1 = ARGV[1];local value2 = ARGV[2];

这样的话你是不是看明白了呢,逗号前后的参数是两种不同的传值方式而已。

  1. 如何在Java程序中执行lua呢 你只需要这样的一段代码就可以调用redis执行脚本redis-ratelimiter-tokenBucket.lua了
@Autowired   private RedisTemplate redisTemplate;   public void counterConsume(String key, String limit, String lrefreshInterval) {     DefaultRedisScript<Long> consumeRedisScript=new DefaultRedisScript();       consumeRedisScript.setResultType(Long.class);       consumeRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/redis-ratelimiter-tokenBucket.lua")));//加载lua脚本文件       List<Object> keyList = new ArrayList();       keyList.add(key);//通过KEYS[1]取值       keyList.add(limit);//通过KEYS[2]取值       List<Object> argvList = new ArrayList();       argvList.add(lrefreshInterval);//通过ARGV[1]取值       String result=redisTemplate.execute(redisScript,keyList,argvList).toString();   }点击下方“阅读原文”查看源码!!!

本文分享自微信公众号 - Java学习录(Javaxuexilu)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

没吃透Netty底层通讯原理,还能算得上Java老司机?

搞了N年Java,仍有不少朋友困惑:用了很多年Dubbo,觉得自己挺厉害,跳槽面试时一问RPC,一问底层通讯,一问NIO和AIO,就一脸懵逼,到底该怎么办?

34430
来自专栏程序生活

大数据入门与实战-PySpark的使用教程

Apache Spark是用Scala编程语言编写的。为了用Spark支持Python,Apache Spark社区发布了一个工具PySpark。使用PySpa...

13720
来自专栏JarvanMo的IT专栏

Flutter中几个常见的小白问题

安装Flutter的时候一定没看文档,由于你懂的原因,国内使用Flutter需要配置镜像。为PUB_HOSTED_URL和FLUTTER_STORAGE_BAS...

1.6K30
来自专栏黑泽君的专栏

Java 中:不允许逻辑操作、运算操作放在方法块外面,编译器会进行优化

9530
来自专栏微信公众号:Java团长

Java 最常见的 208 道面试题:第二模块答案

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的co...

25230
来自专栏区块链大本营

中国区块链开发者真实现状:半数只懂皮毛; 数据分析师吃香; Java/Python或成为主流开发语言

近期,CSDN强势发布了《2018-2019中国开发者调查报告》(以下简称「报告」),报告根据2018年的技术趋势和热点,以及市场上出现的新技术为出发,全面覆盖...

13310
来自专栏magicodes

Docker最全教程之使用Docker搭建Java开发环境(十七)

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。J...

36020
来自专栏编程坑太多

『互联网架构』软件架构-java日志体系(17)

简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。

15420
来自专栏代码男人

Java反射技术详解

  相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java...

11720
来自专栏Java架构师进阶

Netty 100万级高并发服务器配置

每一种该语言在某些极限情况下的表现一般都不太一样,那么我常用的Java语言,在达到100万个并发连接情况下,会怎么样呢,有些好奇,更有些期盼。

32410

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励