博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis Eval Script
阅读量:5240 次
发布时间:2019-06-14

本文共 3571 字,大约阅读时间需要 11 分钟。

简介

从Redis 2.6 版本开始,内嵌支持 Lua 环境。通过使用EVALEVALSHA命令可以使用 Lua 解释器来执行脚本。 EVAL和EVALSHA的使用是差不多的(下面有讲区别)。

EVAL命令

语法: EVAL script numkeys key [key ...] arg [arg ...] 。

script:Lua脚本 。numkeys:key的参数个数。访问脚本获取key值:KEYS[1], KEYS[2], ... (KEYS必须大写),获取arg值:ARGV[1], ARGV[2], ...(ARGV必须大写)。

127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 1 1 ONE TWO1) "1"2) "ONE"3) "TWO"

在Lua脚本中可以通过使用redis.call()或redis.pcall()函数调用redis命令。

127.0.0.1:6379> set foo barOK127.0.0.1:6379> eval "return redis.call('set','foo','bibi')" 0OK127.0.0.1:6379> get foo"bibi"127.0.0.1:6379> eval "return redis.call('set',KEYS[1],'bar')" 1 foo OK

 至于redis.call(),redis.pcall()的不同,在于错误提示不一样

127.0.0.1:6379>  eval "return redis.call('setset','yyyy','oo')" 0(error) ERR Error running script (call to f_9b37f897c55c73737f181184c9781281dc9b45e3): @user_script:1: @user_script: 1: Unknown Redis command called from Lua script127.0.0.1:6379>  eval "return redis.pcall('setset','yyyy','oo')" 0(error) @user_script: 1: Unknown Redis command called from Lua script127.0.0.1:6379>

Redis与Lua数据类型的转换

在Lua脚本通过redis.call()或redis.pcall()执行redis命令,发生数据类型转换:redis命令返回值--------------->lua数据类型。

Lua脚本在Redis内嵌的解释器运行,发生数据类型珠海:lua数据类型-------------->redis命令返回值。

Lua数据类型转Redis类型

  • Lua number  -> Redis integer reply (the number is converted into an integer)
    127.0.0.1:6379> eval "return 9" 0
    (integer) 9
  • Lua string -> Redis bulk reply  bulk类型支持多种数据类型批量返回
    127.0.0.1:6379> eval "return 'hengheng'" 0
    "hengheng"
  • Lua table (array) -> Redis multi bulk reply (truncated to the first nil inside the Lua array if any)
    127.0.0.1:6379> eval "return{'3','rr',4}" 0
    1) "3"
    2) "rr"
    3) (integer) 4
  • Lua table with a single ok field -> Redis status reply ,status类型就是很随意的状态
    127.0.0.1:6379> eval "return {ok='oppp'}" 0
    oppp
  • Lua table with a single err field -> Redis error reply  ,error类型,前面带有括号(error)注明是error类型,区分status类型
    127.0.0.1:6379>  eval "return {err='eeeeeeeeeeee'}" 0
    (error) eeeeeeeeeeee
    127.0.0.1:6379> eval "return {ok='ooooooooooooooo'}" 0
    ooooooooooooooo
  • Lua boolean false -> Redis Nil bulk reply.
    127.0.0.1:6379> eval "return false" 0   
    (nil)

Redis数据类型转lua数据类型:

  • Redis integer reply -> Lua number
  • Redis bulk reply -> Lua string
  • Redis multi bulk reply -> Lua table (may have other Redis data types nested)
  • Redis status reply -> Lua table with a single ok field containing the status
  • Redis error reply -> Lua table with a single err field containing the error
  • Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type

Redis数据类型和lua数据类型并不完全对应:

Lua的编号如果非整数,应作为字符串返回,因为总是转为Redis整数类型

127.0.0.1:6379> eval "return 90.4231" 0

(integer) 90
在Lua数组中使用nils,会停止转换直到数组的最后。

127.0.0.1:6379> eval "return {2332,'rrr','fff',nil,'gg'}"  0

1) (integer) 2332
2) "rrr"
3) "fff"      

运行Lua脚本的原子性

Redis使用Lua解释器解释Lua脚本过程中,会保证脚本是以原子性的方式执行,也就是脚本的效果要么仍然不可见,要么已经完成既然是原子性,那当脚本还没运行完时,其他客户端是无法执行命令的。

所以,该脚本就别搞那么复杂吧,当然,看清况,该复杂也没辙。

EVAL和EVALSHA区别

Eval执行的脚本不从缓存里拿,而Evalsha执行的脚本从缓存拿,跟sha1校验码从服务器缓存里拿。(sha1就好像身份证)

命令:EVALSHA sha1 numkeys key [key ...] arg [arg ...]

127.0.0.1:6379> script load "return 5"    #往缓存里加入脚本 , 返回sha1校验码 "4ca238f611c9d0ae4e9a75a5dbac22aedc379801"127.0.0.1:6379> script exists 4ca238f611c9d0ae4e9a75a5dbac22aedc379801 #是否存在某脚本  1) (integer) 1127.0.0.1:6379> evalsha 4ca238f611c9d0ae4e9a75a5dbac22aedc379801 0 #执行脚本(integer) 5127.0.0.1:6379> script flushOK127.0.0.1:6379> script exists 4ca238f611c9d0ae4e9a75a5dbac22aedc379801 1) (integer) 0     #0表示不存在了127.0.0.1:6379>  evalsha 4ca238f611c9d0ae4e9a75a5dbac22aedc379801 0(error) NOSCRIPT No matching script. Please use EVAL.  #异常了

 

先写到这,待深入。

转载于:https://www.cnblogs.com/bibi-feiniaoyuan/p/9448621.html

你可能感兴趣的文章
OpenFlow 交换机与控制器交互步骤
查看>>
java-内存模型
查看>>
文本相似度比较(网页版)
查看>>
Jenkins关闭、重启,Jenkins服务的启动、停止方法。
查看>>
2019.01.13 bzoj4538: [Hnoi2016]网络(树链剖分)
查看>>
codeforces 315 308
查看>>
BZOJ3998 [TJOI2015]弦论 【后缀自动机】
查看>>
CF E2 - Array and Segments (Hard version) (线段树)
查看>>
svn 架设
查看>>
k8s部署rocketmq 双主
查看>>
Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
查看>>
SIGPIPE并产生一个信号处理
查看>>
CentOS
查看>>
Explicit keyword
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
Erdaicms旅游网站程序,微信扫码登录演示和示例程序
查看>>
15第十五章UDF用户自定义函数(转载)
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>