Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > redis执行lua脚本

redis执行lua脚本的实现

作者:lx18854869896

本文主要介绍了redis执行lua脚本的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

redis EVAL命令可以执行lua脚本,redis保证脚本执行的原子性,脚本由嵌入式执行引擎(Lua 5.1解释器)执行。

1,语法

EVAL script numkeys [key [key ...]] [arg [arg ...]]

第一个参数 script 是脚本的源代码
第二个参数 numkeys 是输入键名参数的数量
后面的就是 key 和 参数。

例如:

> EVAL "return 'Hello, scripting!'" 0
"Hello, scripting!"

其中 "return 'Hello, scripting!'" 就是lua脚本,后面的0就是没有key 也没有参数,可以看到redis返回的就是脚本的返回值。

还有一种方式就是 写一个固定的脚本传递参数,比如

> EVAL "return ARGV[1]" 0 'hello scripting'
"hello scripting"
> EVAL "return ARGV[1]" 0 hello scripting
"hello"
> EVAL "return ARGV[3]" 0 hello scripting
(nil)

可以看到是从[1] 开始获取,而不是[0],参数是以空格隔开,如果超出范围返回nil。

一个使用key的例子

> EVAL "return { KEYS[1], KEYS[2], ARGV[1], ARGV[2], ARGV[3] }" 2 key1 key2 arg1 arg2 arg3
1) "key1"
2) "key2"
3) "arg1"
4) "arg2"
5) "arg3"

可以看到这个lua脚本可以使用{}返回多个值。不知道这个在java 里面返回的是个字符串还是list。

2,调用redis命令

可以通过 redis.call() 或 redis.pcall() 从Lua脚本调用Redis命令。两者几乎相同,除了调用 redis.call() 函数时产生的错误会直接返回到执行该函数的客户端。相反,调用 redis.pcall() 函数时遇到的错误会返回到脚本的执行上下文。
例子:

> EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 foo bar
OK

简单的调用了一个set命令,看起来没有意义,但是多了可以保证原子性就有意义了,比如

> EVAL "local a=redis.call('SET',KEYS[1],ARGV[1]) local b=redis.call('SET',KEYS[2],ARGV[2]) return a and b" 2 k1 k2 v1 v2
OK

3,脚本缓存

> SCRIPT LOAD "return 'Immabe a cached script'"
"c664a3bf70bd1d45c4284ffebb65a6f2299bfc9f"
> EVALSHA c664a3bf70bd1d45c4284ffebb65a6f2299bfc9f 0
"Immabe a cached script"

可以看到使用script load 缓存一个脚本,返回一个ID,之后可以通过evalsha ID 来调用它。

至于lua脚本语言这个东西,摸索着写写就熟悉了。举几个例子:
获取并删除

local value = redis.call('get', KEYS[1]) if value then redis.call('del', KEYS[1]) return value else return nil end

解释,定义一个变量value如果获取到了keys[1]的值,就是删除这个值并返回OK否则返回nil,还可以写成

if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end

看起来跟shell脚本差不多吧。

到此这篇关于redis执行lua脚本的实现的文章就介绍到这了,更多相关redis执行lua脚本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文