Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Sandbox context
2.1.
Global variables and functions
2.2.
Imported Lua modules
3.
Runtime globals
3.1.
The Redis singleton
3.2.
The KEYS global variable
3.3.
The ARGV global variable
4.
Redis object
4.1.
redis.call(command [,arg...])
4.2.
redis.pcall(command [,arg...])
4.3.
redis.error_reply(x)
4.4.
redis.status_reply(x)
4.5.
redis.sha1hex(x)
4.6.
redis.log(level, message)
4.7.
redis.setresp(x)
4.8.
redis.set_repl(x)
4.9.
redis.replicate_commands()
4.10.
redis.breakpoint()
4.11.
redis.debug(x)
4.12.
redis.acl_check_cmd(command [,arg...])
4.13.
redis.register_function
4.14.
redis.REDIS_VERSION
4.15.
redis.REDIS_VERSION_NUM
5.
Data type conversion
5.1.
RESP2 to Lua type conversion
6.
Lua to RESP2 type conversion
6.1.
RESP3 to Lua type conversion
6.2.
Lua to RESP3 type conversion
7.
Frequently Asked Questions
7.1.
What is Redis?
7.2.
What is the meaning of Redis?
7.3.
What language is Redis written in?
7.4.
What is the usage of Redis?
7.5.
What are the ways to interact with Redis?
8.
Conclusion
Last Updated: Mar 27, 2024
Easy

Redis Lua API reference

Author Manan Singhal
0 upvote

Introduction

Redis has a Lua 5.1 interpreter built in. The interpreter executes ephemeral scripts and functions defined by the user. Scripts operate in a sandboxed environment with limited access to Lua packages. This page defines the packages and APIs that are available within the context of the execution.

Sandbox context

The sandboxed Lua context minimizes unintentional usage and mitigates potential server-side vulnerabilities.

Scripts should never attempt to access the underlying host systems of the Redis server. This includes the file system, the network, and any other attempt to make a system call that the API does not support.

Scripts should only work with data saved in Redis and data sent in as parameters to their execution.

Global variables and functions

The declaration of global variables and functions is disabled in the sandboxed Lua execution context. The global variable blocking is in place to ensure that scripts and functions don't try to preserve any runtime context other than the data in Redis. You should keep the context in Redis' keyspace if a context needs to be maintained between executions (which is fairly uncommon).

When attempting to execute the following snippet, Redis will produce the error "Script attempted to create global variable my global variable."

my_global_variable = 'some value'


The following global function declaration is similar:

function my_global_funcion()
  -- Do something amazing
end


When your script tries to access any global variables that are unknown in the runtime's context, you'll get a similar error:

return an_undefined_global_variable


All variable and function definitions must be defined as local instead. To accomplish this, add the local keyword to your declarations. Redis, for example, will regard the following snippet to be fully valid:

local my_local_variable = 'some value'

local function local_function()
  -- Do something else, but amazing
end

Imported Lua modules

The sandboxed execution context does not support the use of imported Lua modules. By deactivating Lua's required function, the sandboxed execution context prohibits modules from being loaded.

Under the Runtime libraries section, you'll find the only libraries that Redis comes with and that you can use in scripts.

Runtime globals

Although the sandbox forbids users from declaring globals, the execution context contains several of them.

The Redis singleton

A redis singleton is an object instance that all scripts can access. It provides an API for scripts to interface with Redis. The following is its description.

The KEYS global variable

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Functions available: no


Only ephemeral scripts have access to the KEYS global variable. All key name input arguments are pre-populated.

The ARGV global variable

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Functions available: no


Only ephemeral scripts have access to the ARGV global variable. All of the standard input arguments are pre-populated.

Redis object

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


An instance of an object named redis is always provided by the Redis Lua execution context. The redis instance allows the script to communicate with the Redis server on which it is running. The API given by the redis object instance is as follows.

redis.call(command [,arg...])

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


The function redis.call() executes a Redis command and returns the result. It takes the command and arguments as inputs and executes the command in Redis before returning the result.

For example, we may use a script to call the ECHO command and receive the following response:

redis.call('ECHO', 'Echo, echo... eco... o...') returns true.


If and when redis.call() throws a runtime exception, and the raw exception is automatically raised as an error and returned to the user.

redis.pcall(command [,arg...])

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


This function allows you to handle Redis server runtime faults. The redis.pcall() function is identical to redis.call() except for the following differences:

  • Returns a response every time.
  • If the server raises a runtime exception, it returns a redis.error reply instead.

redis.error_reply(x)

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


This is a helper function that responds with an error. The helper takes one string parameter and returns a Lua table with that string in the err column.

redis.status_reply(x)

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


This function returns a straightforward string response. A standard Redis status response can be "OK." The Lua API represents status answers as tables with a single field, ok, set with a basic status string.

redis.sha1hex(x)

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


This function returns the SHA1 hexadecimal single string parameter.

You can, for example, get the SHA1 digest of the empty string:

redis> EVAL "return redis.sha1hex('')" 0
"da39a3ee5e6b4b0d3255bfef95601890afd80709"

redis.log(level, message)

  • Since the 2.6.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


This function creates a log entry in the Redis server.

The log level and a message are the two input arguments. The log level can be either of the following:

  • redis.LOG DEBUG
  • redis.LOG NOTICE
  • redis.LOG WARNING
  • redis.LOG VERBOSE


These levels correspond to the log levels on the server. Only messages with a level equal to or greater than the server's log level configuration directive are recorded in the log.

redis.setresp(x)

  • Since the 6.0.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


For the answers produced by redis.call()](#redis.call) and [redis.pall], this function allows the executing script to switch between RESP versions. A single number input specifies the protocol's version. The protocol version 2 is the default, although it can be changed to version 3.

Switching to RESP3 replies is demonstrated in the following example:

redis.setresp(3)

redis.set_repl(x)

  • Version 3.2.0 and up
  • Yes, scripts are available.
  • Functions available: no

redis.replicate_commands()

  • Version 3.2.0 and up
  • Until 7.0.0 version
  • Yes, scripts are available.
  • Functions available: no


This function changes the replication mode of the script from verbatim to effects replication. It can change Redis's default verbatim script replication mode before version 7.0.

Note that verbatim script replication is no longer allowed in Redis v7.0. Script effects replication is the default and only script replication mode supported. Please see Replicating commands rather than scripts for further information.

redis.breakpoint()

  • Version 3.2.0 and up
  • Yes, scripts are available.
  • Functions available: no


This function sets a breakpoint when using the Redis Lua debugger](/topics/ldb).

redis.debug(x)

  • Version 3.2.0 and up
  • Yes, scripts are available.
  • Functions available: no


The Redis Lua debugger console prints the parameter of this function.

redis.acl_check_cmd(command [,arg...])

  • Since the 7.0.0 version
  • Yes, scripts are available.
  • Yes, functions are available.

This function determines whether the current user running the script has ACL permissions to run the specified command with the specified arguments.

If the current user has the authorization to execute the command (through a call to redis.call or redis.pcall), the return value is true; otherwise, it is false.

If the provided command or its arguments are invalid, the function will throw an error.

redis.register_function

  • Since the 7.0.0 version
  • No scripts are available.
  • Yes, functions are available.


This function is only available when the FUNCTION LOAD command is used. It registers a function in the loaded library when it is invoked. Positional or named arguments can be used to call the function.

redis.REDIS_VERSION

  • Since the 7.0.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


As a Lua string, it returns the current Redis server version. The format of the response is MM.mm.PP, where:

  • MM stands for a major version.
  • The minor version is mm.
  • PP stands for patch level.

redis.REDIS_VERSION_NUM

  • Since the 7.0.0 version
  • Yes, scripts are available.
  • Yes, functions are available.


The current Redis server version is returned as a number. The response is a hexadecimal value with the following format: 0x00MMmmPP, where:

  • MM stands for a major version.
  • The minor version is mm.
  • PP stands for patch level.

Data type conversion

redis.call() and redis.pcall() returns the executed command's response to the Lua script unless a runtime exception is raised. The responses from these functions are automatically translated into Lua's native data types by Redis.

When a Lua script uses the return keyword to return a response, the response is automatically translated to Redis' protocol.

There is a one-to-one mapping between Redis responses and Lua data types and a one-to-one mapping between Lua data types and Redis Protocol data types. The underlying design ensures that converting a Redis type to a Lua type and back to a Redis type yields the same result as the original data.

The script's Redis Serialization Protocol version determines how to convert Redis protocol replies (i.e., the responses from redis.call() and redis.pcall()) to Lua data types. During script execution, the default protocol version is RESP2. By using the redis.setresp() function, the script can change the protocol versions of the replies.

The protocol selected by the user determines the returned type conversion from a script, The Lua data type (see the HELLO command).

According to the protocol version, the type conversion rules between Lua and Redis are described in the sections below.

RESP2 to Lua type conversion

By default, and after invoking redis.setresp(2), the following type conversion rules apply to the execution context:

  • RESP2 integer response = Lua number
     
  • RESP2 bulk string response = Lua string
     
  • RESP2 array response = Lua table (may have other Redis data types nested)
     
  • Lua table with a single ok field carrying the RESP2 status string
     
  • Lua table with a single err field carrying the RESP2 error text
     
  • Null bulk reply RESP2 and null multi bulk reply RESP2 -> false boolean type in Lua.

Lua to RESP2 type conversion

By default, and once the user has called HELLO 2, the following type conversion rules apply:

  • RESP2 integer response -> Lua number (the number is converted into an integer)
     
  • RESP bulk string reply -> Lua string
     
  • RESP2 array reply -> Lua table (indexed, non-associative array) (truncated at the first Lua nil value encountered in the table, if any)
     
  • RESP2 status reply -> Lua table with a single ok field
     
  • RESP2 error response from a Lua table with a single err field
     
  • RESP2 null mass reply -> Lua boolean false

There's one more Lua-to-Redis conversion rule that doesn't have a Redis-to-Lua counterpart:

  • RESP2 integer reply with the value of 1 -> Lua Boolean true

There are three more rules to remember when converting Lua data types to Redis data types:

  • Lua numbers are the only numerical type available. No distinction is made between integers and floats. As a result, we always transform Lua numbers into integer responses, omitting any decimal parts. If you want to return a Lua float, you should do so as a string, much like Redis does (see, for instance, the ZSCORE command).
     
  • The table semantics of Lua makes it impossible to have nils inside arrays. When Redis transforms a Lua array to RESP, it comes to a halt when it comes across a Lua nil value.
     
  • When a Lua table is an associative array with keys and values, they are not included in the converted Redis response.

RESP3 to Lua type conversion

The Redis Serialization Protocol has been updated to RESP3. As of Redis v6.0, it is accessible as an opt-in option.

During the execution of a script, the redis.setresp method can be used to change the protocol version used for returning responses from Redis commands (via redis.call() or redis.pcall()).

All of the RESP2 to Lua conversion rules apply once Redis' answers are in RESP3 protocol, with the following additions:

  • RESP3 map response -> Lua table with a single map field containing a Lua table containing the map's fields and values
     
  • RESP set reply -> Lua table with a single set field that contains a Lua table that represents the set's elements as fields, each having the Lua Boolean value of true
     
  • Lua nil -> RESP3 null
     
  • Lua true boolean value -> RESP3 true reply
     
  • Lua false boolean value -> RESP3 false reply
     
  • RESP3 double reply -> Representing the double value
     
  • RESP3 big number reply -> Representing the big number value
     
  • Redis verbatim string reply -> Representing the verbatim string and its format.

Lua to RESP3 type conversion

The user can use RESP3 (with the HELLO 3 command) for the connection regardless of the protocol version chosen for answers with the [redis.setresp() function] when the script calls redis.call() or redis.pcall(). Although RESP2 is the default protocol for incoming client connections, the script should respect the user's preference and deliver properly-typed RESP3 responses. Therefore the following criteria apply to those specified in the Lua to RESP2 type conversion section.

  • RESP3 Boolean reply
     
  • An associative Lua table with a single map field -> RESP3 map reply
     
  • An associative Lua table with a single _set field -> RESP3 set reply Values can be anything and will be thrown anyway
     
  • RESP3 double reply to a Lua table with a single, double field
     
  • RESP3 null = Lua nil

If the connection is configured to utilize the RESP2 protocol, even if the script responds with RESP3-typed responses, Redis will transform the response to RESP2 automatically, just like ordinary commands. For example, it will transform the reply to a flat RESP2 array.

Frequently Asked Questions

What is Redis?

Redis is a key-value data storage and cache that is open-source.

What is the meaning of Redis?

Redis stands for REmote DIctionary Server.

What language is Redis written in?

Redis is a cache solution and session management system developed in ANSI C. It generates one-of-a-kind keys for storing data.

What is the usage of Redis?

Redis is a key-value store database that may be used as a NoSQL database or a memory cache store to boost performance when delivering data from system memory.

What are the ways to interact with Redis?

After the server has been installed, you can either use the Redis Client given by the Redis installation or open a command prompt and type the following command: redis-cli

Conclusion

In this article, we have learned the Redis Lua API reference. We hope that this blog will help you understand the concept of the Redis Lua API reference, and if you would like to learn more about it, check out our other blogs on redismongo-dBdatabase, and operational database.

Attempt our Online Mock Test Series on Coding Ninjas Studio now!

Happy Coding!

Live masterclass