架构师_程序员_码农网

查看: 131|回复: 2

[Redis] Redis 使用 Lua 脚本详解

[复制链接]
发表于 2021-4-30 15:42:57 | 显示全部楼层
关于 redis,大家经常会用得到,用的最多的场景就是数据缓存。

回顾

Redis 持久化 RDB 和 AOF 的区别
https://www.itsvse.com/thread-9555-1-1.html

Docker 安装运行 Redis 缓存
https://www.itsvse.com/thread-8995-1-1.html

实例解读什么是Redis缓存穿透、缓存雪崩和缓存击穿
https://www.itsvse.com/thread-8968-1-1.html

redis 通配符 批量删除key
https://www.itsvse.com/thread-7957-1-1.html

【实战】CentOS 7安装Redis 5.0.3教程
https://www.itsvse.com/thread-7201-1-1.html

【实战】CentOS下php 5.5.7安装redis扩展
https://www.itsvse.com/thread-7200-1-1.html

redis一个实例能存多少key,key与value最大是多少?
https://www.itsvse.com/thread-6848-1-1.html

关于redis中文无法正常显示的问题
https://www.itsvse.com/thread-5032-1-1.html

redis 开启远程访问
https://www.itsvse.com/thread-5011-1-1.html

Windows 无法启动 Redis 服务,错误 1067: 进程意外终止。
https://www.itsvse.com/thread-5010-1-1.html

【实战】centos安装redis 4.0.8
https://www.itsvse.com/thread-4614-1-1.html

redis设置远程连接和访问密码
https://www.itsvse.com/thread-4101-1-1.html

redis 清空数据缓存
https://www.itsvse.com/thread-4027-1-1.html

redis 持久化配置和关闭持久化
https://www.itsvse.com/thread-4012-1-1.html

redis中save和bgsave区别
https://www.itsvse.com/thread-4010-1-1.html

redis 的两种持久化方式及原理
https://www.itsvse.com/thread-4009-1-1.html

Redis 三种启动方式
https://www.itsvse.com/thread-4008-1-1.html

Redis隐藏命令行窗口的方法
https://www.itsvse.com/thread-2988-1-1.html

Redis 哈希(Hash)  Hash取值问题
https://www.itsvse.com/thread-2587-1-1.html

使用Redis之前5个必须了解的事情
https://www.itsvse.com/thread-2580-1-1.html

Redis修改默认端口号以及设置访问密码
https://www.itsvse.com/thread-2577-1-1.html

Redis windows 64位下载,官方下载地址
https://www.itsvse.com/thread-2576-1-1.html
从 redis 2.6.0 版本开始,redis内置了Lua解释器,并提供了eval命令来解析Lua脚本求值。

语法: eval script numkeys keys args

参数:

eval — redis提供解析lua脚本的命令

script — lua脚本

numkeys — 指定键名参数集(keys)的个数

keys — 键名参数集,通过全局变量KEYS数组表示,起始下标为1

args — 键值参数集,通过全局变量ARGV数组表示,起始下标为1


Redis 中使用 Lua 的优点

减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延
原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
复用。客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。

脚本原子性

Lua脚本中不能出现耗时比较长的操作,不能出现死循环,否则redis将不接受其他命令,执行去停止脚本运行了

redis使用单个lua解释器去运行所有脚本,并且保证脚本会以原子性的方式去执行,意味着当某个脚本在运行时,不会有其它脚本或者redis命令被执行!所以,如果当前脚本运行很慢,服务器可能会因为正忙而无法执行命令,如:

每个脚本都有一个最大执行时间限制,默认值是5s。最大执行时间的长短由配置文件redis.conf的lua-time-limit选项来控制,或直接使用config get和config set命令来修改。当一个脚本执行达到最大执行时间,redis不会主动结束它,它会进行下面几个步骤:

①redis记录一个脚本正在超时运行

②redis开始重新接受其它客户端请求,但只接受执行script kill命令和shutdown nosave两个命令,若客户端执行其它命令,redis会返回busy错误。

③如果脚本只执行过读操作,使用script kill命令可以立即停止此脚本;如果脚本执行过写操作,只允许shutdown save/nosave命令,通过停止服务器来阻止当前数据写入磁盘。(此时服务器关闭,数据不会被保存)


示例

执行脚本,参数分别是2个key和value,命令如下:


死循环脚本,执行如下脚本会造成 redis 不能处理其他命令并且卡死:

尝试使用脚本新增一条字符串类型的数据,命令如下:

执行一些更复杂的脚本,如果 key 的 value 等于我们传入的值,才删除该缓存,否则进行任何操作,命令如下:

执行结果如下:

QQ截图20210430154156.jpg

(完)




上一篇:.NET/C# Lock 锁原理 Monitor 深入讲解
下一篇:IIS DELETE PUT 请求 405 解决方案
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 7 天前 | 显示全部楼层

https://redis.io/commands/script-exists
Redis Script Load 命令用于将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。

EVAL 命令也会将脚本添加到脚本缓存中,但是它会立即对输入的脚本进行求值。

如果给定的脚本已经在缓存里面了,那么不执行任何操作。

在脚本被加入到缓存之后,通过 EVALSHA 命令,可以使用脚本的 SHA1 校验和来调用这个脚本。(这也就意味着相同脚本在任意一台不同的redis服务端,执行返回的 sha1 值都是一致的

脚本可以在缓存中保留无限长的时间,直到执行 SCRIPT FLUSH 为止。


QQ截图20210510091806.jpg
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 5 天前 | 显示全部楼层
判断 lua 脚本是否在缓存中


redis 重启后,lua 脚本会自动清除,并不会持久化
QQ截图20210512113727.jpg
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2021-5-17 16:32

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表