Redis之Lua脚本

Redis中内嵌了对Lua环境的支持,允许开发者使用Lua语言编写脚本传到Redis中执行,直接在服务端原子的执行多个Redis命令。

使用Lua脚本的好处:

  1. 减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行
  2. 原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入
  3. 复用性,客户端发送的脚本会永远存储在redis中,其他客户端可以复用这一脚本来完成同样的逻辑

[](https://cpp288.github.io/#Lua%E8%84%9A%E6%9C%AC%E4%BD%BF%E7%94%A8

“Lua脚本使用”)Lua脚本使用

## 在Lua脚本中调用Redis命令

在Lua脚本中调用Redis命令,可以使用redis.call函数调用:

1  
2  
redis.call('set', 'hello', 'world')  
local value = redis.call('get', 'hello')  

—|—

redis.call函数的返回值就是redis命令的执行结果,redis.call函数会将redis的数据类型返回值转换对应的Lua的数据类型,在脚本中可以使用return语句将值返回给redis客户端,如果没有执行return,默认返回为nil

EVAL命令

格式:

1  
[EVAL][脚本内容][key参数的数量][key...][arg...]  

—|—

可以通过key和arg这两个参数向脚本中传递数据,他们的值可以在脚本中分别使用KEYS和ARGV这两个类型的全局变量访问,比如:

Lua脚本:

1  
return redis.call('set',KEYS[1],ARGV[1]) // KEYS和ARGV必须大写  

—|—

EVAL命令:

1  
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 lua1 hello  

—|—

注意:EVAL命令是根据key参数的数量,也就是上面例子中的1来将后面所有参数分别存入脚本中KEYS和ARGV两个表类型的全局变量。当脚本不需要任何参数时也不能省略这个参数,如果没有则设置为0:

1  
eval "return redis.call('get','lua1')" 0  

—|—

[](https://cpp288.github.io/#EVALSHA%E5%91%BD%E4%BB%A4

“EVALSHA命令”)EVALSHA命令

考虑到通过eval执行lua脚本,脚本比较长的情况下,每次调用脚本都需要把整个脚本传给redis,比较占用带宽。为了解决这个问题,redis提供了EVALSHA命令,允许通过脚本内容的SHA1摘要来执行脚本。

该命令用法和EVAL一样,只不过是将脚本内容替换成脚本内容的SHA1摘要:

  1. Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中
  2. 执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了就执行,否则返回“NOSCRIPT No matching script, Please use EVAL”

将脚本加入缓存并生成sha1摘要:

1  
script load "return redis.call('get',"lua1")"  

—|—

使用EVALSHA执行:

1  
evalsha "a5a402e90df3hkfakyi32970058233hjfd574" 0  

—|—

我们在调用eval命令之前,先执行evalsha命令,如果提示脚本不存在,则再调用eval命令

糖果

糖果
LUA教程

Lapis框架的常用处理方法

Lapis框架的常用处理方法 Continue reading

MoonScript实现选择排序

Published on February 26, 2017

MoonScript与Redis客户端

Published on January 19, 2017