📖 Scenario: You are managing a Redis database for a small online store. You want to use Lua scripts inside Redis to perform atomic operations on your data.
🎯 Goal: Build a simple Lua script in Redis that increments a product's stock count safely.
📋 What You'll Learn
Create a Lua script that increments a stock count for a product key
Use Redis commands inside the Lua script
Pass the product key and increment value as arguments to the script
Return the new stock count after increment
💡 Why This Matters
🌍 Real World
Lua scripts in Redis are used to perform multiple commands atomically, which is useful in inventory management systems to avoid race conditions.
💼 Career
Knowing how to write Lua scripts in Redis is valuable for backend developers and DevOps engineers working with Redis to ensure data consistency and performance.
Progress0 / 4 steps
1
Create a Lua script variable
Create a Lua script string variable called lua_script that contains a Redis command to get the current stock count of a product key passed as KEYS[1]. Use redis.call('GET', KEYS[1]) inside the script.
Redis
Hint
Use redis.call to run Redis commands inside Lua scripts.
2
Add increment argument
Add a Lua variable increment inside lua_script that gets the increment value from ARGV[1]. Use tonumber(ARGV[1]) to convert it to a number.
Redis
Hint
Use ARGV[1] to access script arguments passed after keys.
3
Calculate new stock count
Modify lua_script to convert stock to a number (use tonumber(stock) or 0) and add increment to it. Store the result in a variable called new_stock.
Redis
Hint
Use tonumber(stock) or 0 to handle the case when stock is nil.
4
Update stock and return new value
Complete lua_script by setting the new stock count in Redis using redis.call('SET', KEYS[1], new_stock) and then return new_stock.
Redis
Hint
Use redis.call('SET', KEYS[1], new_stock) to update the stock count.
Practice
(1/5)
1. What is the correct way to start a Lua script in Redis using the EVAL command?
easy
A. EVAL redis.call('PING') 0
B. EVAL 'return redis.call("PING")' 0
C. EVAL 'PING' 0
D. EVAL return redis.call('PING') 0
Solution
Step 1: Understand EVAL syntax
The EVAL command requires a Lua script as a string, followed by the number of keys and then the keys and arguments.
Step 2: Check correct Lua script format
The Lua script must be a string and use redis.call to execute Redis commands, e.g., return redis.call("PING").
Final Answer:
EVAL 'return redis.call("PING")' 0 -> Option B
Quick Check:
EVAL with Lua string and 0 keys = A [OK]
Hint: EVAL needs Lua code as string, then number of keys [OK]
Common Mistakes:
Not passing Lua code as a string
Missing return statement in Lua script
Incorrect number of keys argument
Using Redis commands directly without redis.call
2. Which of the following is the correct syntax to call the Redis command SET inside a Lua script?
easy
A. redis.call('SET', 'key', 'value')
B. redis.SET('key', 'value')
C. call.redis('SET', 'key', 'value')
D. redis.call.SET('key', 'value')
Solution
Step 1: Recall Redis Lua API
In Lua scripts for Redis, commands are called using redis.call with the command name as first argument.
Step 2: Check syntax correctness
The correct syntax is redis.call('SET', 'key', 'value'). Other options misuse the API or method calls.
Final Answer:
redis.call('SET', 'key', 'value') -> Option A
Quick Check:
Use redis.call('COMMAND', args...) = B [OK]
Hint: Use redis.call('COMMAND', args) to run Redis commands in Lua [OK]
Common Mistakes:
Using dot notation like redis.SET
Swapping order of arguments
Using call.redis instead of redis.call
Missing quotes around command name
3. What will the following Lua script return when run with EVAL in Redis?
return redis.call('INCR', KEYS[1])
Assuming the key counter does not exist before and the script is called with KEYS[1] = 'counter'.
medium
A. 0
B. Error
C. nil
D. 1
Solution
Step 1: Understand INCR behavior on non-existing key
INCR command creates the key with value 0 then increments it by 1, so the new value is 1.
Step 2: Return value of redis.call('INCR', key)
The call returns the new value after increment, which is 1.
Final Answer:
1 -> Option D
Quick Check:
INCR on new key returns 1 [OK]
Hint: INCR on missing key returns 1 after creating it [OK]
Common Mistakes:
Assuming INCR returns 0 on new key
Expecting nil for missing key
Confusing return value with command success
Not passing KEYS argument correctly
4. Identify the error in this Lua script for Redis:
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])
medium
A. Using local variable val is not allowed
B. Missing return statement in Lua script
C. Using redis.call('INCR') on a string value causes error
D. Incorrect use of KEYS array index
Solution
Step 1: Review the script logic
The script fetches the value with GET. If nil, sets to '1'; else calls INCR, then returns the final GET.
Step 2: Spot the problem with INCR
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.
Step 3: Rule out other options
There is a return statement (not B), local variables are allowed in Redis Lua (not C), and KEYS[1] uses correct 1-based indexing (not D).
Final Answer:
Using redis.call('INCR') on a string value causes error -> Option C
Quick Check:
INCR errors on non-integer strings [OK]
Hint: INCR works on strings representing integers only [OK]
Common Mistakes:
Thinking INCR fails on string '1'
Confusing local variable usage
Assuming missing return statement
Misusing KEYS index
5. You want to atomically increment a counter only if it exists in Redis using a Lua script. Which script correctly implements this?
-- 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
end
hard
A. Option A
B. Option B
C. Option C
D. Option D
Solution
Step 1: Understand requirement
Increment counter only if it exists. If not, return nil without creating it.
Step 2: Analyze the scripts
The script checking redis.call('EXISTS', KEYS[1]) == 1 then returning redis.call('INCR', KEYS[1]) else nil matches exactly. One script calls INCR unconditionally, creating if missing. Another checks if 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). The last increments if EXISTS == 0, opposite of needed.
Final Answer:
Option A -> Option A
Quick Check:
Check EXISTS before INCR to avoid creating key [OK]
Hint: Check EXISTS == 1 before INCR to avoid creating new key [OK]
Common Mistakes:
Incrementing without checking key existence
Using EXISTS == 0 to increment
Not returning correct value after increment
Using GET without handling nil properly
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.