Redis使用Lua脚本命令详解

 更新时间:2023年12月05日 11:00:54   作者:bug生产者  
这篇文章主要为大家介绍了Redis使用Lua脚本命令详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Lua脚本

redis可以支持lua脚本,可以使用lua脚本来将几个命令整合为一个整体来执行,这样可以使得多个命令原子操作,且可以减少网络开销

Lua的数据类型

Lua是一个动态类型的语言,一个变量可以存储任何类型的值,类型有:

  • 空:nil,也就是还没有赋值
  • 字符串:用单引号 或者 双引号
  • 数字:包含整数和浮点型
  • 布尔:boolean
  • 表:表是Lua唯一的数据结构,既可以当数组,也可以做Map,或被视为对象
  • 函数:封装某个或某些功能
  • userData:用来将任意 C 数据保存在 Lua 变量中,这样的操作只能通过 C API
  • Thread:用来区别独立的执行线程,它被用来实现 coroutine (协同例程)

eval命令

redis内有内置的lua解释器,可以使用eval命令对lua脚本进行求值

# script是lua脚本
# numkeys指定键名参数的个数
# key [key ...]  在脚本中使用的redis键,个数为numkeys指定的个数,可以在lua中通过全局变量KEYS数组,从1开始,KEYS[1],KEYS[2]等
# arg [arg ...]  参数,可以在lua中通过全局变量ARGV数组访问,ARGV[1],ARGV[2]等
eval script numkeys key [key ...] arg [arg ...]
#示例:
eval "return {KEYS[1],KEYS[2],ARGV[1]}" 2 key1 key2 first

还可以在lua脚本中调用redis命令,使用redis.call

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

需要注意的是,redis执行lua脚本和普通命令一样,都是会写入AOF文件和发布至主从复制连接上的,有两种方式

  • 第一种方式:和普通命令相同,涉及到的写操作都会记录/发送

    普通命令会转化为redis通信协议的格式,比起lua脚本来说,浪费了更多的带宽,而且slave接收到之后还需要再转换为普通命令

  • 第二种方式:直接将lua脚本记录/发送

    如果直接发送lua脚本,有些命令可能会导致每个机器执行的结果不同,如取随机数等

    这个redis会决定采取哪种方式来执行,在执行前会进行检测写操作是否执行了RANDOMKEY命令,来决定使用哪种方式

evalsha命令

考虑到脚本比较长的情况,如果每次调用脚本都需要将整个脚本传给redis会占用较多的带宽。为了解决该问题,redis提供了evalsha命令允许开发者通过脚本内容的SHA1摘要来执行脚本,该命令的用法的eval一样,不过是将脚本内容替换为脚本内容的SHA1摘要。

redis在执行eval命令时会计算脚本的SHA1摘要并记录在脚本缓存中,执行evalsha命令时redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了则执行脚本,否则返回错误

使用流程

  • 先计算脚本的SHA1摘要,并使用evalsha命令执行脚本
  • 获的返回值,如果返回"NoScript"错误则使用eval命令重新执行脚本

其他不常用的命令

这些命令不是不常用,而是经常被工具类封装起来,开发者如果不深入源码查看,很少会用到

将脚本加入缓存

SCRIPT LOAD命令,作用是每次执行eval命令时redis都会将脚本的SHA1摘要加入到脚本缓存中,以便下次客户端可以使用evalsha命令调用该脚本。如果只是希望将脚本加入缓存而不执行,则使用SCRIPT LOAD命令,返回值是脚本的SHA1摘要

判断脚本是否被缓存

SCRIPT EXISTS命令,可以同时查找多个脚本的SHA1摘要是否被缓存

清空脚本缓存

SCRIPT FLUSH命令,redis将脚本的SHA1摘要加入到脚本缓存后会永久保留,不会删除,可以使用该命令清空脚本缓存

强制终止当前脚本的执行

SCRIPT KILL命令,如果想终止当前正在执行的脚本可以使用该命令

以上就是Redis使用Lua脚本命令详解的详细内容,更多关于Redis使用Lua脚本的资料请关注脚本之家其它相关文章!

相关文章

  • Redis常用数据类型命令实例汇总

    Redis常用数据类型命令实例汇总

    这篇文章主要介绍了Redis常用数据类型命令实例汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Redis两种持久化方案RDB和AOF详解

    Redis两种持久化方案RDB和AOF详解

    这篇文章主要介绍了Redis 两种持久化方案,RDB(Redis DataBase)和 AOF(Append Only File),给大家提供参考,一起学习下。
    2017-11-11
  • Redis简单动态字符串SDS的实现示例

    Redis简单动态字符串SDS的实现示例

    Redis没有直接复用C语言的字符串,而是新建了SDS,本文主要介绍了Redis简单动态字符串SDS的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • php结合redis实现高并发下的抢购、秒杀功能的实例

    php结合redis实现高并发下的抢购、秒杀功能的实例

    下面小编就为大家带来一篇php结合redis实现高并发下的抢购、秒杀功能的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • Redis分布式锁存在的问题(推荐)

    Redis分布式锁存在的问题(推荐)

    有很多基于Redis实现的分布式锁方案或者库,但是有些库并没有解决分布式环境下的一些问题陷阱,这篇文章主要介绍了Redis分布式锁存在的问题,需要的朋友可以参考下
    2022-12-12
  • 一分钟搞懂Redis的慢查询日志操作

    一分钟搞懂Redis的慢查询日志操作

    redis慢查询指的是命令执行时长比较长的查询,本文详细的介绍了慢查询的具体操作,具有一定的参考价值,感兴趣的可以了解一下
    2021-11-11
  • Reactor WebFlux集成Redis处理缓存操作

    Reactor WebFlux集成Redis处理缓存操作

    这篇文章主要为大家介绍了Reactor WebFlux集成Redis处理缓存操作示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Redis内部数据结构Dict的实现方法

    Redis内部数据结构Dict的实现方法

    这篇文章主要介绍了Redis内部数据结构Dict的实现方法,本篇文章所述的dict在Redis中最主要的作用就是用于维护Redis数据库中所有Key、value映射的数据结构,需要的朋友可以参考下
    2022-05-05
  • Redis五种数据结构在JAVA中如何封装使用

    Redis五种数据结构在JAVA中如何封装使用

    本篇博文就针对Redis的五种数据结构以及如何在JAVA中封装使用做一个简单的介绍。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Redis集群详解

    Redis集群详解

    这篇文章主要介绍了Redis集群详解,需要的朋友可以参考下
    2020-07-07

最新评论