Redis 中 Lua 与 Pipeline 的相同点,区别,使用场景

文章目录

一、主要解决的问题

(1) Lua 脚本

主要解决多个命令执行时的原子性问题,确保全部成功或全部失败

使用 Lua 时,可以将多个命令打包到一个 Lua 脚本中,一次性执行,来实现原子性。
多个命令:往往是几个,几十个,几百个的量级

(2) Pipeline(管道)

主要解决执行大批量命令时,消耗过多网络资源的问题

使用 Pipeline 时,可以将多个命令打包到一个 Pipeline 管道中,减少执行大量命令时每次都需要的网络开销,提高效率。
大量批命令:往往是几百,几千,几万的量级

二、相同点

Lua 和 Pipeline 也有一些相同点:

  1. 批量操作 :都支持将多个 Redis 命令组合在一起执行
  2. 性能优化 :两者都用于减少网络往返时间(RTT),提高 Redis 操作的性能
  3. 减少网络开销 :通过减少客户端与服务器之间的通信次数来提升效率
  4. 顺序执行 :多个命令是按顺序执行

三、区别

对比维度 Lua 脚本(EVAL/EVALSHA) Pipeline(管道)
执行位置 在 Redis 服务端执行(Lua 引擎) 客户端打包发送,服务端逐条执行
原子性 ✅ 是,全部成功或失败 ❌ 否,可能部分成功,部分失败
是否独占资源 ✅ 是,Redis 会阻塞其他所有客户端请求,保证脚本内所有操作不可分割 ❌ 否,命令按序执行,但执行过程中可能被其他命令"插队"
阻塞风险 复杂脚本可能长时间阻塞 Redis 单线程 只是减少 RTT,不会额外阻塞
性能瓶颈 脚本过长会阻塞 Redis 线程,导致其他请求处于等待状态 性能极高,适合大量无依赖命令批量处理,其他请求可能穿插执行
错误处理 redis.call() 出错会中断脚本;redis.pcall() 可捕获错误继续执行 某条命令失败不影响后续命令执行(无事务回滚)
网络开销 脚本内容需传输一次(可用 SCRIPT LOAD + EVALSHA 缓存 SHA1 避免重复传输) 多条命令合并为一次 TCP 请求,减少 RTT
逻辑复杂性 是,支持复杂逻辑:条件判断、循环、局部变量等完整编程能力,可以调用 Lua 函数 否,只是简单的命令堆叠,仅支持命令批量发送,无逻辑控制能力

四、使用场景

使用时,主要取决于业务场景

(1) Lua 脚本

需要原子性(全部成功或失败)或逻辑判断时,使用 Lua 脚本。常见场景有:

  • 分布式锁
  • 库存扣减
  • 订单创建
  • 用户注册
  • 限流(令牌桶/计数器)
  • 转账(一个扣款 → 另一个加款)

(2) Pipeline

需要大批量执行命令,命令之间无依赖,减小网络开销,使用 Pipeline。常见场景有:

  • 批量查询、更新、删除(如:10万条商品数据写入 Redis,商品数据之间无需原子操作)
  • 初始化缓存
  • 日志/埋点数据上报

五、注意事项

Lua 脚本

  1. 避免在 Lua 中进行大量计算,Redis 是单线程的
  2. 脚本执行时间不宜过长(建议 < 100ms)
  3. 使用SCRIPT KILL可以终止长时间运行的脚本(除非脚本修改了数据)

Pipeline

  1. 合理设置批量大小,过大会增加内存使用和延迟
  2. 注意 Redis 服务器的输出缓冲区限制
  3. 考虑使用异步或非阻塞方式处理 Pipeline 结果
相关推荐
曲幽3 小时前
FastAPI多进程部署:定时任务重复执行?手把手教你用锁搞定
redis·python·fastapi·web·lock·works
wWYy.4 小时前
详解redis(15):缓存雪崩
数据库·redis·缓存
这周也會开心5 小时前
Redis相关知识点
数据库·redis·缓存
Anastasiozzzz6 小时前
Redis的键过期是如何删除的?【面试高频】
java·数据库·redis·缓存·面试
thulium_7 小时前
Redis Cluster + Docker + --net=host在 WSL2 下是一个“看起来能跑,实际上必失败”的组合
redis·docker
打工的小王9 小时前
Redis(二)数据类型
数据库·redis·缓存
笨蛋不要掉眼泪11 小时前
Redis核心数据类型与命令
数据库·redis·缓存
小唐同学爱学习12 小时前
短链接修改之写锁
spring boot·redis·后端·mysql
zhglhy12 小时前
Redis Cluster 的数据分片机制
数据库·redis·缓存