Redis如何通过Lua减少网络通信开销
一次EVAL比多次SET/GET更快,因网络往返是Redis高并发隐性瓶颈;EVAL将读+算+写全过程压缩至1次RTT,而多命令需4次以上,且redis.call()为内部调用无额外开销。为什么一次 EVAL 比多次 SET/GET 更快因为网络往返(round-trip)是 Redis 高并发下的隐性瓶颈。客户端发一条命令、等响应、再发下一条,光 TCP 往返延迟在跨机房场景就可能达 10–50ms;而 EVAL 把逻辑“塞进服务端”执行,只用一次请求完成读+算+写全过程。典型场景:秒杀扣库存——先 GET 库存,再 DECR,再判断是否为负,再 SET 新值。不用 Lua 至少 4 次 RTT;用 Lua 只需 1 次注意:redis.call() 在脚本内调用命令不产生新网络开销,它走的是内部函数调用路径,不是 client-server 协议栈别指望 Lua 脚本“加速单条命令”,它的价值永远在“多步协同”。单独用 EVAL "return redis.call('GET', KEYS[1])" 1 mykey 反而比原生命令慢一点(多了脚本解析开销)EVALSHA 是怎么省带宽的EVALSHA 不是语法糖,它是 Redis 的脚本缓存机制落地方式:首次用 SCRIPT LOAD 提交脚本,Redis 返回一个 SHA1 摘要(比如 "a1b2c3d4..."),之后所有执行都只传这个 40 字符摘要,而不是几百字节的完整 Lua 源码。实操建议:上线前用 SCRIPT LOAD 预热所有业务脚本,避免运行时首次 EVAL 触发重复加载和 SHA 计算集群环境要注意:SCRIPT LOAD 必须发到对应 key 所在 slot 的节点,否则 EVALSHA 会报错 (error) NOSCRIPT No matching script. Please use EVAL.Spring Boot 项目里如果用 Lettuce,记得开启 ScriptExecutor 自动管理 SHA 缓存,否则每次重启都重新 LOAD,反而增加初始化压力KEYS 和 ARGV 传参不规范的后果Redis 强制要求键名必须通过 KEYS 数组传入,不能拼在 Lua 字符串里(比如 "mykey:"..ARGV[1])。这是为了支持集群分片——Redis 需提前从 KEYS 提取所有涉及的 key,计算 slot 并路由到正确节点。 RedClaw 百度推出的手机端万能AI Agent助手
