一、引言

redis学了一段时间了,基本的东西都没问题了。从今天开始讲写一些redis和lua脚本的相关的东西,lua这个脚本是一个好东西,可以运行在任何平台上,也可以嵌入到大多数语言当中,来扩展其功能。lua脚本是用C语言写的,体积很小,运行速度很快,并且每次的执行都是作为一个原子事务来执行的,我们可以在其中做很多的事情。由于篇幅很多,一次无法概述全部,这个系列可能要通过多篇文章的形式来写,好了,今天我们进入正题吧。

二、lua简介
    
               Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。

Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

三、EVAL命令的详解

   1、EVAL简介(Introduction to EVAL)

Redis从其2.6.0版本或者更高的版本以后,可以使用 Lua脚本解释器的 EVAL命令和 EVALSHA 命令测试评估脚本。

EVAL命令的第一个参数是一个 Lua5.版本1的脚本。脚本不需要定义一个Lua函数(不应该)。它仅仅是一个在Redis服务器的上下文中运行的Lua程序。

EVAL命令的第二个参数紧跟Lua脚本后面的那个参数,这个参数表示KEYS参数的个数,从第三个参数开始代表Redis键名称。Lua脚本可以访问由KEYS全局变量(如KEYS [1],KEYS [2],...)组成的一维数据的参数。

EVAL最后附加的参数表示的是对应KEYS键名所对应的值,并且Lua脚本可以通过使用ARGV全局变量的访问其值,和KEYS数组的情况差不多(所以ARGV[1],ARGV[2],...)。

以下示例应该阐明上述内容:

> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"

注意:正如你所看到的,作为Redis批量回复的形式返回了Lua数组,这是Redis返回的一种类型,在我们实现的客户端库(针对某种语言实现的Redis操作库)中应该会将其转换为针对该编程语言中的特定Array类型。

可以使用两个不同的Lua函数从Lua脚本调用Redis命令:
 
redis.call()

redis.pcall()

redis.call()与redis.pcall()非常类似,唯一的区别是,如果Redis命令调用发生了错误,redis.call() 将抛出一个Lua类型的错误,再强制EVAL命令把错误返回给命令的调用者,而redis.pcall()将捕获错误并返回表示错误的Lua表类型。

redis.call()和redis.pcall()函数的参数是Redis命令和命令所需要的参数:

                       > eval "return redis.call('set','foo','bar')" 0OK

上面的脚本的意思是:将键foo的值设置为字符串的bar,和(set foo bar)命令意义相同。但是它违反了EVAL命令的语义,因为Lua脚本使用的所有键应该通过使用KEYS数组来传递进来:

                      > eval "return redis.call('set',KEYS[1],'bar')" 1 fooOK

在执行之前,必须分析所有的Redis命令,以确定命令将在哪些键上运行。为了使EVAL命令执行成功,必须明确传递所需的键。这在很多方面都很有用,但特别要确保Redis群集可以将您的请求转发到适当的群集节点。
                     (All Redis commands must be analyzed before execution to determine which keys the command will operate on. In order for this to be true for EVAL, keys must be passed explicitly. This is useful in many ways, but especially to make sure Redis Cluster can forward your request to the appropriate cluster node.)

请注意,此规则未实施,为用户提供滥用Redis单实例配置的机会,这是以编写与Redis集群不兼容的脚本为代价的。
                     (Note this rule is not enforced in order to provide the user with opportunities to abuse the Redis single instance configuration, at the cost of writing scripts not compatible with Redis Cluster.)

Lua脚本可以使用一组转换规则返回从Lua类型转换为Redis协议的值。
                     (Lua scripts can return a value that is converted from the Lua type to the Redis protocol using a set of conversion rules.)

参考文章:

1. Redis进阶实践之十九 Redis如何使用lua脚本 - 可均可可 - 博客园

2.PHP中使用redis执行lua脚本示例 - tai君 - 博客园

PHP中使用redis执行lua脚本示例相关推荐

  1. PHP中使用redis 执行lua脚本

    在php中,可以通过redis执行lua脚本 1.脚本 <?php $redis = new Redis(); #实例化redis类 $redis->connect('127.0.0.1' ...

  2. redis执行lua脚本

    从redis 2.6.0版本开始,redis内置了Lua解释器,并提供了eval命令来解析Lua脚本求值. 1. 语法格式 语法: eval script numkeys keys args 参数: ...

  3. Redis脚本插件之————执行Lua脚本示例

    Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行.使用脚本的好处如下: 1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在red ...

  4. 【已解决】Java 项目中利用 Redis 配合 Lua 脚本对短信推送消息做推送限制

  5. redis之lua脚本: 原子性 调试 嵌入高级语言

    实验环境: redis: 6.0.9 redis执行lua脚本时, 出错不会回滚(rollback) 我们知道, 使用lua脚本可以在执行一串redis命令时, 实现一定原子性(lua脚本中多条指令执 ...

  6. Redis:EVAL执行Lua脚本

    EVAL 脚本 numkeys 键[键...] arg [arg ...] 自Redis2.6.0版本起可用. 时间复杂度:取决于执行的脚本. EVAL介绍 EVAL和EVALSHA用于从Redis2 ...

  7. Redis进阶-lua脚本

    文章目录 Pre 语法 jedis操作lua 好处 lua实战 注意事项 Pre Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行. 语法 从Redis2.6.0 ...

  8. Redis 使用 Lua 脚本进行原子操作

    Redis 使用 Lua 脚本进行原子操作 Intro 之前写过一篇文章也是 Redis 使用 LUA 脚本实现分布式的 CAS 操作,可以参考:基于 Redis 实现 CAS 操作 最近使用 Red ...

  9. Redis使用Lua脚本:保证原子性【项目案例分享】

    文章目录 前言 Lua脚本原子性介绍 Redis执行Lua的原生EVAL命令 案例1:生成雪花算法workerId 背景 技术方案 Jedis调Lua源码 案例2:限制并发更新课件播放进度 背景 技术 ...

最新文章

  1. 网络嗅探与欺骗(FTP部分)
  2. Windows7 VMware虚拟机安装Apple Mac OSX v10.7 Lion
  3. MyBatis+Spring MVC开发指南(一)
  4. 神经网络与深度学习——TensorFlow2.0实战(笔记)(三)(python运算符和表达式)
  5. 数据结构与算法(C#版)第二章 C#语言与面向对象技术(下)V1.0
  6. 计算机组成原理r型指令logisim实现_第一章 计算机体系结构
  7. 爬虫python代码网易云_python-网易云简单爬虫
  8. 系统学习数字图像处理之图像分割
  9. System Operations on AWS - Lab 7 - CloudFormation
  10. 鲁宾逊微积分是什么?
  11. 5G 当自强,根系不能忘
  12. (4)bootstrap标签页
  13. 2018——广东工业大学校赛题解
  14. mysql本机ip一般是多少_localhost简介、localhost与 127.0.0.1 及 本机IP 的区别
  15. 马化腾发飚了:很多业务该砍就要砍
  16. onclick绑定多事件
  17. linux系统下 安装docker
  18. 分形插值matlab,分形插值算法和MATLAB实验
  19. 数字 和 大小写字母之间的转换 10进制和26进制之间的转换
  20. EV录屏有很大电流音的解决方法

热门文章

  1. Vs2015 mysql ef_VS2015 +EF6 连接MYSQL数据库生成实体
  2. 120000字,你们要的Java 并发编程图文小册整理出来了,免费送给大家!
  3. 每日一皮:用户永远不知道怎么用我们的产品...
  4. 升级 | Fastjson 1.2.68 发布,支持 GEOJSON
  5. Spring Cloud Stream消费失败后的处理策略(一):自动重试
  6. 死磕Java并发:J.U.C之并发工具类:CountDownLatch
  7. python50种算法_收藏 | 一文洞悉Python必备50种算法(附解析)
  8. 8月25号王者荣耀服务器维护,8月25日体验服停机更新公告
  9. pytorch 单机多卡训练distributedDataParallel
  10. python 获取类名