Concept Flow - Lua script syntax in Redis
Start Script
Define Variables
Use Redis Commands
Return Result
End Script
A Lua script in Redis starts, defines variables, runs Redis commands, returns a result, and ends.
local val = redis.call('GET', KEYS[1]) if val == false then return 'No value' end return val
| Step | Action | Evaluation | Result |
|---|---|---|---|
| 1 | Call redis.call('GET', KEYS[1]) | KEYS[1] = 'mykey' | val = 'hello' |
| 2 | Check if val == false | val = 'hello' | Condition false |
| 3 | Return val | val = 'hello' | Output: 'hello' |
| 4 | End script | Script ends |
| Variable | Start | After Step 1 | After Step 2 | Final |
|---|---|---|---|---|
| val | nil | 'hello' | 'hello' | 'hello' |
Lua scripts in Redis:
- Use redis.call('COMMAND', args) to run Redis commands
- KEYS and ARGV hold input keys and arguments
- Use local variables to store results
- Return a value with return statement
- redis.call returns false if key missingEVAL 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