当前位置: 首页 > news >正文

滚雪球学Redis[6.2讲]:Redis脚本与Lua:深入掌握Redis中的高效编程技巧

全文目录:

    • 📝前言
    • 🚦正文
      • 🌟6.2.1 Lua脚本的优势
      • 🖋️6.2.2 EVAL命令与Lua脚本编写
        • 🐵编写Lua脚本的基本步骤
        • 🐶示例:简单的GET和SET操作
        • 🐱示例:Lua实现自增和过期时间
      • 🧨6.2.3 Lua脚本的安全性与性能优化
        • 🐯安全性问题
        • 🦊性能优化
    • 🎮️过渡展望:Redis分布式锁
    • ⚡总结

📝前言

在上期内容【6.1 Redis事务】中,我们探讨了Redis中的事务机制,尤其是如何通过MULTIEXECWATCH命令来确保数据的一致性。尽管Redis的事务功能为多个命令提供了原子性,但在处理复杂的业务逻辑时,这种方式常常显得力不从心。为了应对这一挑战,Redis引入了Lua脚本功能,使得开发者可以在Redis中编写更加复杂的操作逻辑,提升了灵活性和效率。

本期内容【6.2 Redis脚本与Lua】将着重介绍使用Lua脚本的优势、如何编写和执行Lua脚本、以及脚本的安全性和性能优化。通过具体的案例,读者可以更直观地理解Lua脚本在实际应用中的强大功能。此外,在下期内容【6.3 Redis分布式锁】中,我们将深入探讨如何利用Redis实现分布式锁机制,确保在分布式环境下的数据一致性与同步,敬请期待!🔐

🚦正文

🌟6.2.1 Lua脚本的优势

在Redis中使用Lua脚本有几个显著的优势,能够有效提升应用程序的性能和灵活性:

  1. 减少网络开销
    Redis是一个基于请求/响应模型的系统。每次请求都需要经过网络往返,这在处理多个命令时尤其影响性能。通过Lua脚本,开发者可以将多个命令组合到一个脚本中,这样可以显著减少网络延迟,从而提升整体性能。

    示例

    -- 假设需要对多个键执行操作
    local value1 = redis.call('GET', KEYS[1])
    local value2 = redis.call('GET', KEYS[2])
    return value1 + value2
    

    在没有Lua脚本的情况下,客户端需要发送两次请求,而使用Lua脚本只需发送一次请求即可。

  2. 操作的原子性
    使用Lua脚本可以确保脚本中的所有操作都以原子方式执行。这意味着,如果脚本中的任何一个命令失败,Redis会保证没有任何命令被执行。这对于保持数据一致性至关重要。

  3. 支持复杂逻辑
    Lua是一种功能强大的编程语言,支持条件判断、循环和函数等结构。开发者可以使用Lua编写复杂的逻辑,从而减少客户端代码的复杂性。

    示例

    -- 使用Lua实现条件逻辑
    local count = redis.call('GET', KEYS[1])
    if count and tonumber(count) > 10 thenreturn '超过限制'
    elseredis.call('INCR', KEYS[1])return '已增加计数'
    end
    

🖋️6.2.2 EVAL命令与Lua脚本编写

Redis使用EVAL命令来执行Lua脚本。其基本语法如下:

EVAL script numkeys key [key ...] arg [arg ...]
  • script:Lua脚本内容
  • numkeys:传入的key数量
  • key:要操作的Redis键
  • arg:脚本中的参数
🐵编写Lua脚本的基本步骤
  1. 加载脚本
    将Lua脚本加载到Redis中,通常通过EVAL命令直接执行。

  2. 编写脚本
    根据业务逻辑编写Lua脚本,可以使用Redis的各种命令。

  3. 执行脚本
    使用EVALEVALSHA命令来执行脚本。

🐶示例:简单的GET和SET操作
-- Lua脚本示例:从Redis获取值,如果不存在则设置默认值
local value = redis.call('GET', KEYS[1])  -- 获取key对应的值
if not value thenredis.call('SET', KEYS[1], ARGV[1])   -- 如果key不存在,设置默认值value = ARGV[1]
end
return value

执行方式

EVAL "local value = redis.call('GET', KEYS[1]); if not value then redis.call('SET', KEYS[1], ARGV[1]); value = ARGV[1]; end; return value" 1 mykey "default_value"

在这个示例中,Lua脚本尝试获取键的值,如果键不存在,则设置默认值。

🐱示例:Lua实现自增和过期时间
-- Lua脚本示例:对某个键进行自增操作,并设置过期时间
local current = redis.call('INCR', KEYS[1])
if current == 1 thenredis.call('EXPIRE', KEYS[1], ARGV[1])  -- 只有在键第一次自增时,设置过期时间
end
return current

执行方式

EVAL "local current = redis.call('INCR', KEYS[1]); if current == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]); end; return current" 1 mycounter 60

在这个示例中,Lua脚本对mycounter键进行自增操作,并在第一次自增时设置过期时间为60秒。

🧨6.2.3 Lua脚本的安全性与性能优化

🐯安全性问题
  1. 脚本注入
    Lua脚本也可能遭遇脚本注入问题,尤其是在处理用户输入时。为了避免这种情况,应该尽量使用KEYSARGV参数传递用户输入,而不是直接嵌入到脚本中。

    防止注入示例

   -- 不安全的方式,可能引发脚本注入local user_input = ARGV[1]local unsafe_script = "redis.call('SET', 'user:" .. user_input .. "', 'value')"-- 安全的方式,使用ARGV传递redis.call('SET', KEYS[1], ARGV[1])
  1. 脚本超时
    Redis提供了一个配置选项lua-time-limit,用于限制Lua脚本的执行时间。若脚本超过此时间,Redis会强行终止。
   CONFIG SET lua-time-limit 10000  # 设置Lua脚本执行时间限制为10秒
🦊性能优化
  1. 缓存脚本
    Redis会为每个Lua脚本进行编译。为了提升性能,可以使用EVALSHA命令执行脚本的SHA1摘要,从而避免重复编译。

    示例

   local sha1 = redis.call('SCRIPT', 'LOAD', "your_lua_script")

然后使用EVALSHA命令执行:

   EVALSHA sha1 numkeys key [key ...] arg [arg ...]
  1. 减少内部Redis命令调用
    在编写Lua脚本时,应尽量减少redis.call的调用次数。虽然每次调用都在Redis内部执行,但仍会引入开销。合并逻辑或通过批量操作提升执行效率。

    示例

   -- 合并多个命令为一个逻辑local value1 = redis.call('GET', KEYS[1])local value2 = redis.call('GET', KEYS[2])return value1 + value2  -- 只需一次返回

🎮️过渡展望:Redis分布式锁

在下一期【6.3 Redis分布式锁】中,我们将深入探讨如何利用Redis实现分布式锁。这在分布式系统中具有重要意义,可以确保多个节点之间的数据一致性和同步。我们将详细讲解分布式锁的实现原理、常见的实现方式(如SETNX、Redlock等),以及如何避免锁的死锁问题。通过这些知识,你将能够更有效地管理分布式环境中的资源,确保系统的高可用性和稳定性。

下期亮点

  • 深入了解分布式锁的工作原理
  • 实现锁的获取与释放
  • 优化分布式锁的性能与安全性

敬请期待!🎯


⚡总结

Redis中的Lua脚本为开发者提供了强大的编程能力,能够简化多命令操作,确保操作的原子性和执行效率。通过合理编写和优化Lua脚本,开发者可以大幅提升Redis的性能,减少网络通信开销。在实际项目中,Lua脚本的使用不仅提升了代码的可读性和可维护性,还能在复杂业务逻辑的实现上展现其独

特优势。

希望本期内容能帮助你更深入地理解和运用Redis脚本与Lua,为你的开发工作带来便利。如果你有任何问题或讨论,欢迎在评论区分享!✨

相关文章:

滚雪球学Redis[6.2讲]:Redis脚本与Lua:深入掌握Redis中的高效编程技巧

全文目录: 📝前言🚦正文🌟6.2.1 Lua脚本的优势🖋️6.2.2 EVAL命令与Lua脚本编写🐵编写Lua脚本的基本步骤🐶示例:简单的GET和SET操作🐱示例:Lua实现自增和过期…...

上市不到一月,极氪7X交付破万台!论纯电,极氪真“遥遥领先”

承认吧,在纯电这条赛道上,极氪真就“遥遥领先”~ 推出的第一款原生纯电猎装极氪001,就常年霸榜25万级豪华纯电销冠 主打豪华大车的极氪009,成为40万以上高端“保姆车”的不二之选 第一次面向主流纯电市场推出的豪华大五座——极…...

【Linux】理解文件系统与软硬链接,观察inode号理解<“软链接是包含路径的新文件“,“硬链接是关于文件名的机制“>,最终明白<什么是真正删除一个文件>

前言 大家好吖,欢迎来到 YY 滴Linux系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Lin…...

Java高并发控制之按业务对象加同步锁

一、需求 最常见的一个场景,账户余额更新! 业务场景稍复杂点,一个客户有多个虚拟余额账户,产生交易时,需要同时更新客户的多个余额账户,现在需要为余额更新做并发控制。 二、解决方案 1、依赖数据的乐观锁&…...

Python魔法函数__iter__的用法

下面是找到的一个比较好的科学解释: Python中可迭代对象(Iterable)并不是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )方法或__getitem__( )方法访问。 1.__iter__方法的作用是让对象可以用for…...

Redis-缓存一致性

缓存双写一致性 更新策略探讨 面试题 缓存设计要求 缓存分类: 只读缓存:(脚本批量写入,canal 等)读写缓存 同步直写:vip数据等即时数据异步缓写:允许延时(仓库,物流&a…...

SAP学习笔记 - 豆知识13 - Msg 番号 NR751 - Object RF_BELEG R100、番号範囲間隔 49 不存在 FBN1

其实这种就是自动採番的番号没弄。 比如跨年了,那该新年度的番号范围没弄啊,就会出这种错误。 把番号范围给加一下就可以了。 1,现象 比如点 VL02N 出荷传票变更 画面,点 出库确认 就会出如下错误: Object RF_BEL…...

美摄科技云服务解决方案,方案成熟,接入简单

美摄科技作为视频处理领域的先锋,凭借其强大的技术实力和深厚的行业经验,推出了成熟的云服务解决方案,为轻量化视频制作开辟了全新的道路。 一、成熟方案,接入无忧 美摄科技云服务解决方案的最大亮点在于其成熟度和易用性。我们…...

【bug】paddleocr draw_ocr_box_txt ValueError: incorrect coordinate type

【bug】paddleocr draw_ocr_box_txt ValueError: incorrect coordinate type 环境 python 3.10.15pillow 10.4.0 paddleocr 2.8.1错误详情 错误文本 Traceback (most recent call last):....draw_left.polygon(box, fillcolor)ValueError: inco…...

python的多线程和多进程

首先需要明确的是,多进程和其他语言的一样,能够利用多核cpu,但是python由于GIL的存在,多线程在执行的时候,实际上,每一时刻只有一个线程在执行。相当于是单线程。然而多线程在某些情况下,还是能…...

基于SpringBoot+Vue+uniapp的时间管理小程序的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…...

HMAC-MD5参数签名算法

更多中电联在线工具 HMAC-MD5 是一种基于 MD5 哈希函数的消息认证码(MAC)算法。它用于确保消息的完整性和认证,通常用于数据传输和 API 请求。其基本步骤如下: 密钥准备:选择一个密钥(K)&#…...

【word】文章里的表格边框是双杠

日常小伙伴们遇到word里插入的表格,边框是双杠的,直接在边框和底纹里修改边框的样式就可以,但我今天遇到的这个有点特殊,先看看表格在word里的样式是怎么样,然后我们聊聊如何解决。 这个双杠不是边框和底纹的设置原因…...

我常用的两个单例模式写法 (继承Mono和不继承Mono的)

不继承Mono 不继承Mono代表不用挂载到场景物体上面,因此直接饿汉式 加 合并空运算符判空创建实例 >(lambda表达式)的意思是get,就是将instance赋给Instance属性 //单例private static JsonDataManager instance new JsonDataManager();public stati…...

Android 自定义Toast显示View

1、创建一个tosat显示的布局文件&#xff1a;toast_custom.xml <?xml version"1.0" encoding"utf-8"?> <com.hjq.shape.layout.ShapeLinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width&…...

SCRM呼叫中心高保真Axure原型 源文件分享

在数字化时代&#xff0c;客户关系管理&#xff08;CRM&#xff09;对于企业的成功至关重要。SCRM呼叫中心后台作为一款专为CRM设计的软件原型&#xff0c;致力于为企业提供高效、智能的客户沟通解决方案。本文将详细介绍该产品的核心功能及其对企业提升客户满意度和销售业绩的…...

Ubuntu(Linux)tcpdump使用方法详解

tcpdump命令 1.从所有网卡获取数据包 tcpdump -i any2.从指定网卡获取数据包 tcpdump -i eth03.指定网卡&#xff0c;IP&#xff0c;写文件 tcpdump -i eth0 host 192.168.16.101 -w ./tcp.dat //host 后面是发送方的地址4.指定网卡&#xff0c;源IP且目的IP&#xff0c;写入…...

Centos安装Nginx 非Docker

客户的机器属于 Centos7 系列&#xff0c;由于其较为陈旧&#xff0c;2024开始众多镜像和软件源都已失效。此篇文章将详细记录在 Centos7 操作系统上从零开始安装 Nginx 的整个流程。 本文Nginx是安装在/usr/local/nginx下 详细步骤如下&#xff1a; 准备Nginx安装包&#x…...

免费版的音频剪辑软件:这四款有没有你的菜?

随着音频编辑需求的日益增长&#xff0c;免费的音频剪辑软件逐渐成为许多创作者、学生和普通用户的心头好。今天&#xff0c;就让我为大家介绍几款热门的免费音频剪辑软件&#xff0c;并分享一下我的使用感受吧&#xff01; 一、福昕音频剪辑 直通车&#xff08;复制粘贴到网站…...

Facebook的隐私之战:数据保护的挑战与未来

在数字化时代&#xff0c;隐私保护成为了公众关注的焦点&#xff0c;尤其是在社交媒体巨头Facebook身上。随着用户数据泄露事件的频发&#xff0c;Facebook面临着日益严峻的隐私挑战。这些挑战不仅涉及法律法规的遵循&#xff0c;还影响着用户信任、公司声誉以及未来的发展方向…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...