Redis 脚本
用 Lua 脚本在服务端原子执行复杂逻辑。
Key PointsLua 脚本在服务端单线程执行,天然原子,是「读-改-写」复杂操作的标准解。
EVAL 基础
Shell
EVAL "return redis.call('GET', KEYS[1])" 1 mykeyOutput
(nil)原子限流示例
LUA
-- KEYS[1]=限流 key, ARGV[1]=窗口秒数, ARGV[2]=上限
local cnt = redis.call('INCR', KEYS[1])
if cnt == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[1])
end
if cnt > tonumber(ARGV[2]) then
return 0
end
return 1Run this via EVAL (or SCRIPT LOAD then EVALSHA). The rate-limit check completes in one atomic step, with no race between 'check passed' and 'not yet written'.
A Lua script blocks the whole Redis while running (single thread), so keep scripts short — no loops that could run long, or the entire server stalls.
EVAL 基础
Shell
EVAL "return redis.call('GET', KEYS[1])" 1 mykeyOutput
(nil)原子限流示例
LUA
-- KEYS[1]=限流 key, ARGV[1]=窗口秒数, ARGV[2]=上限
local cnt = redis.call('INCR', KEYS[1])
if cnt == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[1])
end
if cnt > tonumber(ARGV[2]) then
return 0
end
return 1把这段脚本 EVAL 执行(或 SCRIPT LOAD 后 EVALSHA 复用),限流判断在单线程里一气呵成,不会有「判断通过但还没写就被并发突破」的竞态。
Lua 脚本执行期间会阻塞整个 Redis(单线程),所以脚本必须短小、不能有死循环或长耗时代码,否则整个服务卡住。