在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、为什么要使用Lua脚本的好处 1、减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延和请求次数。
二、redis本地客户端调用示例基本介绍 EVAL 和 EVALSHA 命令是从 Redis 2.6.0 版本开始的,使用内置的 Lua 解释器,可以对 Lua 脚本进行求值。 redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...] 参数说明:
实例 xxx>eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name ling OK xxx>get name "ling" 在redis中编写lua脚本时,可以通过KEYS与ARGV来传入外部参数,每个KEY都是通过KEYS表指定。ARGV表用来传递参数,这个例子中ARGV用来传入name的值。 关于EVALSHA命令
为了减少带宽的消耗, Redis 实现了 EVALSHA 命令,它的作用和 它会根据给定的 sha1 校验码,执行缓存在服务器中的脚本。
三、什么时候使用Lua三个主要优点:原子性,减少网络io,速度快。 关于WATCH/MULTI/EXEC与lua的区别与选择 Redis支持WATCH/MULTI/EXEC这样的块,能进行一组操作,也能一起提交执行,看起来与Lua有重叠。应该如何进行选择? MULT块中所有操作独立,但在Lua中,后面的操作能依赖前面操作的执行结果。同时使用Lua脚本还能够避免WATCH使用后竞争条件引起客户端反应变慢的情况。 在RedisGreen(译注:国外一家专门提供Redis主机的服务商),我们看到许多应用使用Lua的同时也使用MULTI/EXEC,但两者但不是替代关系。许多成功的Lua脚本都很小,仅仅实现一个你的应用需要而Redis命令中没有单一的功能。 四、访问库Redis的Lua解释器加载七个库:base,table,string, math, debug,cjson和cmsgpack。前几个都是标准库,充许你使用任何语言进行基本的操作。后面两个可以让Redis支持JSON和MessagePack—这是非常有用的功能,同时我也很想知道为什么常常看不到这种用法。 Web应用程序常常使用JSON作为api返回数据,你也许也可以把一堆JSON数据存到Redis的key中。当想访问某些JSON数据时,首先需要保存到一个hash中,使用Redis的JSON支持将非常方便: if redis.call("EXISTS", KEYS[1]) == 1 then local payload = redis.call("GET", KEYS[1]) return cjson.decode(payload)[ARGV[1]] else return nil end 在这里我们检查看key是否存在,如不存在则快速返回nil。如存在则从Redis中获取JSON值,用cjson.decode()进行解析,然后返回请求内容。 redis-cli set apple '{ "color": "red", "type": "fruit" }' => OK redis-cli eval "$(cat json-get.lua)" 1 apple type => "fruit" 加载这段脚本进你的Redis服务器,将JSON数据保存到Redis中,通常是hash。 虽然我们每次访问时都必须解析,但只要你的对象很小,这个操作实际上是非常快的。 如果你的API只是在内部提供,通常需要考虑效率上的问题,MessagePack 是比采用JSON更好的选择,它更小,更快,在Redis(更多场合也是如此),MessagePack是JSON更好的替代品。 if redis.call("EXISTS", KEYS[1]) == 1 then local payload = redis.call("GET", KEYS[1]) return cmsgpack.unpack(payload)[ARGV[1]] else return nil end
五、Redis与lua数据类型转换当 Lua 通过 call() 或 pcall() 函数执行 Redis 命令的时候,命令的返回值会被转换成 Lua 数据结构。 redis返回值类型和Lua数据类型转换规则 整数回复 数字类型
字符串回复 字符串类型
多行字符串回复 table类型(数组形式)
状态回复 table类型(只有一个ok字段存储状态信息)
错误回复 table类型(只有一个err字段存储错误信息)
Lua数据类型和redis返回值类型转换规则 数字类型 整数回复(Lua的数字类型会被自动转换成整数)
字符串类型 字符串回复
table类型(数组形式) 多行字符串回复
table类型(只有一个ok字段存储状态信息) 状态回复
table类型(只有一个err字段存储错误信息) 错误回复
Python 示例pool = redis.ConnectionPool(host='xxx',port=6379, decode_responses=True) conn = redis.Redis(connection_pool=pool) def luatest(): lua1 = """ """ script2 = conn.register_script(lua1) script2(keys=[],args=[]) 编程中一些注意的地方: 1.lua脚本中调用redis命令使用call与pcall命令。 2.Wrong number of args calling Redis command From Lua script此报错为使用redis调用命令的使用参数不完整,比如有些操作hash的命令,需要两个key,掉了一个key就会出现此错误。 3.lua脚本中支持多返回值,lua中使用table存储,返回时直接返回此table,python接收为一个list的。 实际示例:使用redis存储聊天数据(lua)
总结:下面这些都是在Redis中使用Lua时常见的错误:
|
请发表评论