I am building out my first Redis server side script (for debugging) and my lack of Lua experience has me quite stuck.
Essentially have a dataset of K/V pairs (containing ~1000 values) from which I want to list all the KEYS that match a pattern. For example in redis-cli:
> KEYS "carlos:*"
1) "carlos:1"
2) "carlos:2"
3) "carlos:3"
4) "carlos:4"
Based on the above output I want to return the sum of those keys by executing a Lua script. Currently I have the following on my sum.lua
local sum = 0
local matches = redis.call('KEYS', 'carlos:*')
for unpack(matches)
sum = sum + redis.call('GET', matches)
end
return sum
While the above script is likely incorrect, trying even redis.call('KEYS', 'carlos:*')
by itself produces the following error
root@carlos:~# redis-cli EVAL "$(cat sum.lua)"
(error) ERR wrong number of arguments for 'eval' command
I have tried a number of iterations of my syntax to no avail. Any ideas?
Thanks
Executing Lua in Redis. Redis lets users upload and execute Lua scripts on the server. Scripts can employ programmatic control structures and use most of the commands while executing to access the database. Because scripts execute in the server, reading and writing data from scripts is very efficient.
Rate Limiting Lua Script Redis has the ability to execute Lua scripts on the server side. Lua scripts are executed atomically, that is, no other script or command will run while a script is running, which gives us the same transactional semantics as MULTI / EXEC .
call() will raise a Lua error that in turn will force EVAL to return an error to the command caller, while redis. pcall will trap the error returning a Lua table representing the error." So according to the documentation , in the case of using redis.
EVAL
requires a minimum of two arguments; the script and the number of keys you are passing to the script. In this case, you are passing zero keys, meaning the script can be invoked as follows:
redis-cli EVAL "$(cat sum.lua)" 0
or:
redis-cli --eval sum.lua
Your loop structure for iterating over the values returned from KEYS
was incorrect; I have fixed it for you.
You need to convert the value returned from GET
from a string to a number using Lua's tonumber
function.
With the above changes made, the following script should work for you:
local sum = 0
local matches = redis.call('KEYS', 'carlos:*')
for _,key in ipairs(matches) do
local val = redis.call('GET', key)
sum = sum + tonumber(val)
end
return sum
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With