Redis OSS Lua scripts
Redis OSS supports more than 200 commands, including those to run Lua scripts. However, when it comes to Lua scripts, there are several pitfalls that can affect memory and availability of Redis OSS.
Unparameterized Lua scripts
Each Lua script is cached on the Redis OSS server before it runs. Unparameterized Lua scripts are unique, which can lead to the Redis OSS server storing a large number of Lua scripts and consuming more memory. To mitigate this, ensure that all Lua scripts are parameterized and regularly perform SCRIPT FLUSH to clean up cached Lua scripts if needed.
The following example shows how to use parameterized scripts. First, we have an example of an unparameterized approach that results in three different cached Lua scripts and is not recommended:
eval "return redis.call('set','key1','1')" 0 eval "return redis.call('set','key2','2')" 0 eval "return redis.call('set','key3','3')" 0
Instead, use the following pattern to create a single script that can accept passed parameters:
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key1 1 eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key2 2 eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key3 3
Long-running Lua scripts
Lua scripts can run multiple commands atomically, so it can take longer to complete than a regular Redis OSS command. If the Lua script only runs read-only operations, you can stop it in the middle. However, as soon as the Lua script performs a write operation, it becomes unkillable and must run to completion. A long-running Lua script that is mutating can cause the Redis OSS server to be unresponsive for a long time. To mitigate this issue, avoid long-running Lua scripts and test the script out in a pre-production environment.
Lua script with stealth writes
There are a few ways a Lua script can continue to write new data into Redis OSS even when Redis OSS is over maxmemory
:
The script starts when the Redis OSS server is below
maxmemory
, and contains multiple write operations insideThe script's first write command isn't consuming memory (such as DEL), followed by more write operations that consume memory
You can mitigate this problem by configuring a proper eviction policy in Redis OSS server other than
noeviction
. This allows Redis OSS to evict items and free up memory in between Lua scripts.