Introduction
Lua scripts in Redis let you run multiple commands together safely and quickly without interruptions.
EVAL script numkeys key [key ...] arg [arg ...]
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return redis.call('GET', KEYS[1])" 1 mykey newvalue
EVAL "local val = redis.call('INCR', KEYS[1]); return val" 1 counter
EVAL "local current = redis.call('GET', KEYS[1]); if not current then redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1] else return current end" 1 greeting Hello
EVAL command?redis.call to execute Redis commands, e.g., return redis.call("PING").SET inside a Lua script?redis.call with the command name as first argument.redis.call('SET', 'key', 'value'). Other options misuse the API or method calls.EVAL in Redis?return redis.call('INCR', KEYS[1])counter does not exist before and the script is called with KEYS[1] = 'counter'.local val = redis.call('GET', KEYS[1])
if val == nil then
redis.call('SET', KEYS[1], '1')
else
redis.call('INCR', KEYS[1])
end
return redis.call('GET', KEYS[1])redis.call('INCR', KEYS[1]) will raise an error if the key's existing value is a non-integer string (e.g., 'abc'). The script does not validate the value type before incrementing.-- Option A
if redis.call('EXISTS', KEYS[1]) == 1 then
return redis.call('INCR', KEYS[1])
else
return nil
end
-- Option B
return redis.call('INCR', KEYS[1])
-- Option C
if redis.call('GET', KEYS[1]) then
redis.call('INCR', KEYS[1])
end
return redis.call('GET', KEYS[1])
-- Option D
if redis.call('EXISTS', KEYS[1]) == 0 then
return redis.call('INCR', KEYS[1])
else
return nil
endredis.call('EXISTS', KEYS[1]) == 1 then returning redis.call('INCR', KEYS[1]) else nil matches exactly.redis.call('GET', KEYS[1]) (truthy for any non-nil), calls INCR but returns subsequent GET (may error on non-integers or not return increment directly).EXISTS == 0, opposite of needed.Pass the test and this pattern moves unknown