Redis之使用lua脚本操作redis数据库的原因
2017-11-06 16:10
691 查看
前言
为什么要用lua脚本操作redis数据库?1.减少开销–减少向redis服务器的请求次数
2.原子操作–redis将lua脚本作为一个原子执行
3.可复用–其他客户端可以使用已经执行过的lua脚本
4.增加redis灵活性–lua脚本可以帮助redis做更多的事情
lua脚本本身体积小,启动速度快.
因此,从redis 2.6.0开始,redis在服务器端内置lua解释器
EVAL命令语法
EVAL script numkeys key [key …] arg [arg …]EVAL —lua程序的运行环境上下文
script —lua脚本
numkeys —参数的个数(key的个数)
key —redis键 访问下标从1开始,例如:KEYS[1]
arg —redis键的附加参数
lua脚本
EVAL和EVALSHA用redis内置的lua编译器执行脚本举例说明:
123456 | 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username password test 1234561) "username"2) "password"3) "test"4) "123456"127.0.0.1:6379> |
lua函数
主要有两个函数来执行redis命令redis.call() – 出错时返回具体错误信息,并且终止脚本执行
redis.pcall() –出错时返回lua table的包装错误,但不引发错误
举例说明:
123 | 127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name redisOK127.0.0.1:6379> |
redis.call()出错时:
123 | 127.0.0.1:6379> eval "return redis.call('get',KEYS[1],ARGV[1])" 1 name redis(error) ERR Error running script (call to f_b943d620b079a29d99eccaaa7317e05f8eb8ce88): @user_script:1: @user_script: 1: Wrong number of args calling Redis command From Lua script 127.0.0.1:6379> |
123 | 127.0.0.1:6379> eval "return redis.pcall('get',KEYS[1],ARGV[1])" 1 name redis(error) @user_script: 1: Wrong number of args calling Redis command From Lua script127.0.0.1:6379> |
lua与redis数据类型转换
lua通过redis.call()或者redis.pcall()函数执行redis命令的返回值被转换成了lua数据结构,当然了,当lua脚本在redis的内置解释器里运行时,lua脚本的返回值也会被转换成redis数据结构,然后由EVAL将值返回给客户端.那么lua和redis数据类型之间时如何转换的呢?对应关系又是怎样的呢?
redis数据类型 | lua数据类型 |
---|---|
integer | number |
bulk | string |
multi bulk | table |
status | 包含ok域的table |
error | 包含err域的table |
nil bulk | false |
从lua转换到redis有一条额外的对应规则
lua boolean true –> redis 1
即,lua的true对应redis 的整型1.
EVAL和EVALSHA
EVAL命令在每次执行脚本时,都发送一次脚本主体,而EVALSHA并非如此,它的第一个参数时脚本的sha1校验和.EVALSHA命令的机制如下:
如果服务器记得SHA1校验和指定的脚本,那么执行该脚本
如果服务器不记得SHA1校验和指定的脚本,那么它返回一个错误,提醒用户使用EVAl代替EVALSHA
因此在脚本主体不变的情况下使用EVALSHA,可以使脚本复用,而节省带宽
lua脚本要求
脚本需要被写成纯函数对于同样的数据输入,给定相同的参数,脚本执行的redis写命令的结果总是相同的.
为此,redis做了以下事情:
lua没有访问系统时间或者其他内部状态的命令
redis阻止上面所提到的脚本执行
lua脚本调用返回序命令的返回数据会被排序(字典序.)
对 Lua 的伪随机数生成函数 math.random 和 math.randomseed 进行修改,使得每次在运行新脚本的时候,总是拥有同样的 seed 值.
不允许创建全局变量
为了防止数据泄露进lua环境,redis脚本不循序创建全局变量.
访问一个全局变量(无论是否存在)都会引起脚本停止
总结
使用lua操作redis数据库能够带来很多便利,后续将提供实例展示lua脚本是如何操作redis数据库的.
相关文章推荐
- Redis使用lua脚本实现increase + expire 的原子操作
- lua脚本操作redis数据库
- 使用lua脚本和jedis实现redis的hmsetnx命令,操作hash表时不覆盖原有数据
- 简介Lua脚本与Redis数据库的结合使用
- nodejs 使用 generic-pool 操作 redis数据库
- Nginx 内嵌lua脚本,结合Redis使用
- 操作、压缩MDB文件;使用ADO读写Mysql数据库;建立数据库和表的VBS脚本代码(2013-08-26 11:39:34)
- 【COCOS2DX-LUA 脚本开发之十】使用Lua CJSON库进行encode与decode操作完成对Json数据转化
- 【COCOS2DX-LUA 脚本开发之十】使用Lua CJSON库进行encode与decode操作
- PHP使用Redis+Lua脚本操作的注意事项
- 在redis一致性hash(shard)中使用lua脚本的坑
- redis实现附近的人,但jedis中没有相关api,那么直接使用lua脚本执行。
- 使用node_redis进行redis数据库crud操作
- redis中的事务、lua脚本和管道的使用场景
- PHP中使用redis执行lua脚本示例
- mongod使用js脚本对数据库进行操作
- SoapUI中使用Groovy脚本操作数据库
- Redis中使用Lua脚本的开发思路
- Window:使用Lua 操作Redis
- 使用bat脚本进行数据库操作