• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

初探Lua脚本

武飞扬头像
dotaer-df
帮助5

1、什么是Lua

  Lua脚本是一个由C语言编写的小巧脚本语言,在所有脚本引擎中,Lua的速度是最快的。Lua的核心代码不过一万多行,因为是C语言编写的,因此Lua可以在几乎所有的操作系统和平台进行编译运行

2、Lua适用场景

1)、辑相对简单,没有复杂的数据交互,访问频次超高的接口实现

2)、 lua适合的是无阻塞的,如果脚本含有文件读写,也快不到哪去

常见搭配:

Nginx lua 开发高性能web应用,限流、防止sql注入、请求过滤,黑白名单限制等等等。

redis lua  实现原子操作,避免多线程数据不一致的问题

3、Lua安装以及基本语法

1)Lua安装教程

2)Lua基本语法

学过java的人,看Lua脚本应该也是手到擒来,这里就不展开讲了。

4、Redis中使用Lua

Redis 2.6 版本之后才通过内嵌支持 Lua 环境,在Redis中通过Lua脚本可以实现原子操作,因为Redis服务端会将Lua脚本当作一条命令去执行,同时如果程序中存在多次Redis交互的场景,也可以通过讲这些命令合并写到一个脚本中,这些减少了网络交互次数,也间接的提升了性能,不过也要保证脚本不要太大,过于复杂。

核心命令:EVAL

EVAL script numkeys key [key …] arg [arg …]
  • script:lua脚本程序
  • numkeys:  用于指定键名参数的个数
  • key [key...]:从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
  • arg [arg ...]:附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

比如说执行这样一个命令

EVAL "local num = 1; redis.call('set',KEYS[1],ARGV[1]   num) return redis.call('get',KEYS[1])" 1 testKey 10

其中script参数对应的脚本如下 

学新通

numkeys的参数对应1,表示后面有几个key

key的参数对应testKey,只有一个key

arg参数对应10,也就是这个key对应的value

这条命令的意思就是定义了一个num,然后往里面set进了一个值,KEYS[1] 也就是传入的参数key,ARGV[1]也就是传入的value,然后进行相加,最后脚本返回相加的一个结果为11。

学新通

这样就将原本两个命令先set,再get替换成了一个原子命令去执行。

这里再以Redission作为客户端演示一下,代码里面如何去执行:

  1.  
    public static void main(String[] args) throws Exception{
  2.  
    Config config = new Config();
  3.  
    config.useSingleServer().setAddress("redis://localhost:6379");
  4.  
    config.useSingleServer().setPassword("123456");
  5.  
     
  6.  
     
  7.  
    RedissonClient client = Redisson.create(config);
  8.  
    RScript rScript = client.getScript();
  9.  
     
  10.  
    String script = "local num = 1;"
  11.  
    "redis.call('set',KEYS[1],ARGV[1] num);"
  12.  
    "return redis.call('get',KEYS[1])";
  13.  
    Integer value = rScript.eval(RScript.Mode.READ_WRITE, script, RScript.ReturnType.VALUE, Collections.singletonList("key"), 10);
  14.  
    System.out.println("直接执行脚本:" value);
  15.  
     
  16.  
    }
学新通

学新通

 在调用api的时候,大家可能会发现eval和evalsha这两个api,其实这两个都是用来执行lua脚本的。但是eval命令是直接发送lua脚本的,而evalsha是发送一个之前执行过的lua脚本的,使用evalsha命令可以减少lua脚本网络发送的开销,不过要注意的是,在使用evalsha这个命令时,要先把脚本 预加载到Redis服务器上,例如这样:

  1.  
    String script = "local num = redis.call('get',KEYS[1]);"
  2.  
    "redis.call('set',KEYS[1],ARGV[1] num);"
  3.  
    "return redis.call('get',KEYS[1])";
  4.  
    // 预加载脚本
  5.  
    String shaDigest = rScript.scriptLoad(script);
  6.  
     
  7.  
    Integer value2 = rScript.evalSha(RScript.Mode.READ_WRITE, shaDigest, RScript.ReturnType.VALUE, Collections.singletonList("key"), 10);
  8.  
    System.out.println("执行缓存脚本:" value2);

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhhbik
系列文章
更多 icon
同类精品
更多 icon
继续加载