Redis has multiple commands that work on a number of keys. For example, you can use „MSET“ to set a number of keys to individual values. And you can use „SET“ or „SETEX“ to set a single key to a value with expire time. However, there is no command that handles multiple keys with expire time.
Since you can run lua-scripts in Redis, it is possible to build a custom MSETEX-command with lua. Here is the lua-code:
for i=1, #KEYS, 1 do redis.call('SET', KEYS[i], ARGV[(i*2)-1] , 'EX', ARGV[(i*2)]) end return 'OK'
Remarks:
- in contrast to some programming languages, lua uses 1 as the first index of a collection
- „return ‚OK'“ is needed for vert.x, as vert.x-redis requires a non-null result
I’m not a lua expert, so feel free to improve the script if you spot something.
OK, the script is there, how do I use it? I use vert.x, so the first thing to do is set up a redis connection. Use „scriptLoad“ to send the script to redis, and store the result-hash. Now you can use the „evalsha“ command to run the script with your values. Here is some java-code for vert.x:
List<String> keys = new ArrayList<>(entries.size()); List<String> values = new ArrayList<>(entries.size()*2); for (int i = 0; i < 2; i++) { keys.add(i, "key"+i); values.add((i*2),"value"); values.add((i*2)+1,"60"); //TTL in seconds } redisConnection.evalsha(msetexHash,keys,values,handler);
Remarks:
- Collections are 0-based in java, thus the index magic is differs from lua
- For each key you must specify 2 values: first the payload to set, then the ttl
- error handling not implemented here
- msetexHash must be initialized with the result of the „script load“ command
- while the script is evaluated, redis blocks. Run some tests before using a large number of keys