前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >lua脚本操作redis数据库

lua脚本操作redis数据库

作者头像
编程珠玑
发布2019-09-03 16:05:07
2.3K0
发布2019-09-03 16:05:07
举报
文章被收录于专栏:编程珠玑编程珠玑

前言

为什么要用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编译器执行脚本 举例说明

代码语言:javascript
复制
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username password test 123456
1) "username"
2) "password"
3) "test"
4) "123456"
127.0.0.1:6379>

上面lua脚本的意思是返回以lua数组的形式返回key1,key2和value1,value2,2是key的个数.

lua函数

主要有两个函数来执行redis命令 redis.call() – 出错时返回具体错误信息,并且终止脚本执行 redis.pcall() –出错时返回lua table的包装错误,但不引发错误 举例说明:

代码语言:javascript
复制
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username password test 123456
1) "username"
2) "password"
3) "test"
4) "123456"
127.0.0.1:6379>

该脚本中的函数作用是类似于执行 set name redis 的redis命令.并返回执行结果,ok

redis.pcall()出错时:

代码语言:javascript
复制
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 script
127.0.0.1:6379> 

redis.call()出错时:

代码语言:javascript
复制
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> 

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

从redis数据类型到lua数据类型或者从lua数据类型到redis数据类型,都有以上对应规则,但是从

从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数据库的.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程珠玑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • EVAL命令语法
    • lua脚本
      • lua函数
      • lua与redis数据类型转换
      • EVAL和EVALSHA
      • lua脚本要求
      • 总结
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档