官方文档 : http://redisdoc.com/script/eval.html
基本命令
EVAL | 用于调试或运行脚本 |
SCRIPT LOAD | 生成指定脚本的sha1校验码 |
EVALSHA | 运行sha1脚本 |
SCRIPT EXISTS | 检测sha1是否存在缓存中 |
SCRIPT FLUSH | 清除所有 Lua 脚本缓存 |
SCRIPT KILL | 杀死当前正在运行的 Lua 脚本。 |
避免引入全局变量的一个诀窍是:将脚本中用到的所有变量都使用 local
关键字定义为局部变量。
在 Lua 脚本中,可以使用两个不同函数来执行 Redis 命令,它们分别是:
-
redis.call()
-
redis.pcall()
案例:
原命令:
##1、获取当前有序集合的第一名信息
127.0.0.1:6379> zRevRange ranking_rich_list 0 0 withscores
1) "19315"
2) "58142.5"
##2、给当前用户增加积分
127.0.0.1:6379> zincrby ranking_rich_list 10 11848
"15640.305200730394"
编写lua脚本,实现在每次增加积分的时候先查询原始第一名的数据保证原子性,解决并发时取到的第一名有误差的问题。
"local top1 = redis.call('zRevRange',KEYS[1],0,0,'WITHSCORES'); local score = redis.call('zincrby',KEYS[1],ARGV[1],ARGV[2]); return {top1, score}"
解释:第一段脚本
local top1 = redis.call('zRevRange',KEYS[1],0,0,'WITHSCORES');
使用local声明局部变量参数top1,使用call执行redis命令,
第一个参数是redis命令,第二个KEYS[1]参数是zRevRange key名,第三个参数0是start,第4个参数是stop,第五个参数就是zRevRange 的WITHSCORE,最后的结果会赋值给top1。
注意:lua接参下标都是从1开始而不是从0
最后使用 retuen返回两个参数值,最终这个lua脚本就需要传三个参数
KEYS[1] = redis key名
ARGV[1] = zincrby 命令的 increment参数
ARGV[2] = zincrby 命令的 member参数
测试:
## 使用eval测试脚本
127.0.0.1:6379> eval "local top1 = redis.call('zRevRange',KEYS[1],0,0,'WITHSCORES'); local score = redis.call('zincrby',KEYS[1],ARGV[1],ARGV[2]); return {top1, score}" 1 ranking_rich_list 10 11848
1) 1) "19315"
2) "58142.5"
2) "15650.305200730394"
## 生成sha1校验码
127.0.0.1:6379> script load "local top1 = redis.call('zRevRange',KEYS[1],0,0,'WITHSCORES'); local score = redis.call('zincrby',KEYS[1],ARGV[1],ARGV[2]); return {top1, score}"
"66448d0c16571ae1e5039d243174382377435aa5"
## 使用evalsha 运行lua脚本取到结果
127.0.0.1:6379> evalsha 66448d0c16571ae1e5039d243174382377435aa5 1 ranking_rich_list 10 11848
1) 1) "19315"
2) "58142.5"
2) "58091.305200730392"
127.0.0.1:6379> evalsha 66448d0c16571ae1e5039d243174382377435aa5 1 ranking_rich_list 500 11848
1) 1) "19315"
2) "58142.5"
2) "58591.305200730392"
127.0.0.1:6379> evalsha 66448d0c16571ae1e5039d243174382377435aa5 1 ranking_rich_list 10 11848
1) 1) "11848"
2) "58591.305200730392"
2) "58601.305200730392"