初探Lua脚本

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作为客户端演示一下,代码里面如何去执行:

	public static void main(String[] args) throws Exception{
		Config config = new Config();
		config.useSingleServer().setAddress("redis://localhost:6379");
		config.useSingleServer().setPassword("123456");


		RedissonClient client = Redisson.create(config);
		RScript rScript = client.getScript();

		String script = "local num = 1;" +
				"redis.call('set',KEYS[1],ARGV[1] + num);" +
				"return redis.call('get',KEYS[1])";
		Integer value = rScript.eval(RScript.Mode.READ_WRITE, script, RScript.ReturnType.VALUE, Collections.singletonList("key"), 10);
		System.out.println("直接执行脚本:"+value);

	}

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

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

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值