ruk·si

🟥 Redis
📜 Scripts

Updated at 2024-02-24 11:02

Scripts (and more modern variants, Functions) are server-side Lua code executed on the Redis server, effectively reducing the number of round trips between client and server.

Everything you can do with a Redis transaction, you can also do with a script, and usually the script will be both simpler and faster.

-- HSET_X: set a hash field to value if the hash exists
local key = KEYS[1];
if redis.call('exists', key) ~= 0 then
    return redis.call('hset', key, unpack(ARGV));
end
return 0;

Script results should be small. Redis stores the results of the Lua script in memory which can lead in higher memory usage.

Scripts should be light and efficient as Redis server is single-threaded. Redis has lua-time-limit with the default value of 5 seconds. After that value, the server will respond BUSY Redis is busy running a script. to incoming requests. Before that value connections are just blocked like normal.

Consider the following if you start noticing BUSY errors:

  • Break your script into smaller pieces.
  • If your script is read-only, and you have a Redis cluster, run that script in a replica.
  • In rare cases, increasing lua-time-limit value can be acceptable but then all clients must-know how to handle long blocking Redis calls (e.g., with a timeout + retry later) instead of relying on BUSY error + trying again.

If you have an essential, long-running script, run it during low-activity hours.

Scripts in Clusters

Your script must only access keys that reside on a single server, and Redis must know what that server is so that it can route the script there.

  • If you're not using Redis cluster, then these conditions will always be met, since there's only one server.
  • If you are using Redis cluster, then you must specify at least one key, and all keys that the script uses must be located on the same server as the specified keys.

Redis keys are sorted into hash slots. The cluster's key space is split into 16384 hash slots. Each node in a cluster handles a subset of those 16384 hash slots.

default:
HASH_SLOT = CRC16(key) mod 16384

You can customize this with {} hash tag notation in.

The two keys {user1000}.following and {user1000}.followers will hash to the same hash slot since only the substring user1000 will be hashed to compute the hash slot.

This allows multi-key operations in Redis clusters.

So, keys that contain {thing} can be accessed by a script that has {thing}.something as one of the declared keys.

Both multi-key operations and scripts may become unavailable when a resharding of the hash slot the keys belong to is in progress. So sometimes you might have to try again.

Error: TRYAGAIN

It's obviously good to reshard during low-activity hours.