Help Center/ GeminiDB/ GeminiDB Redis API/ Development Reference/ Lua Script Compilation Specifications
Updated on 2024-08-06 GMT+08:00

Lua Script Compilation Specifications

Lua is a scripting language designed to be embedded in applications to provide flexible extension and customization functions for applications. GeminiDB Redis API uses Lua 5.1.5, which is the same as the Lua version used by the open-source Redis 5.0.

When you use Lua scripts, make sure to perform a careful verification. Otherwise, infinite loops, request timeouts, or other exceptions may occur, or even services may become unavailable.

Differences from Open-Source Redis Lua

  1. EVAL/EVALSHA

    Example command:

    EVAL script numkeys key [key ...] arg [arg ...]

    EVALSHA sha1 numkeys key [key ...] arg [arg ...]

    You can use the preceding commands the same as you do in open-source Redis. Ensure that the Redis key used in the script is explicitly transferred through the key instead of being directly encoded in the script.

    If a cluster instance is used and multiple key parameters are specified, all key parameters must have the same hash tag.

    If the preceding constraints are not complied with, error messages may be returned and data consistency may be damaged when Redis operations involving these keys are performed in Lua.

  2. SCRIPT

    SCRIPT contains a group of subcommands for managing Lua scripts. You can run SCRIPT HELP to query specific operations.

    Most SCRIPT commands are compatible with open-source Redis. The following commands that need to be noted:

    • SCRIPT KILL

      GeminiDB Redis API is a multi-thread execution environment, so it allows multiple Lua scripts to be executed at the same time. If SCRIPT KILL is executed, all running Lua scripts will be terminated.

      For ease of use, it extends the SCRIPT KILL command. You can use SCRIPT KILL SHA1 to terminate the script of a specified hash value. If multiple nodes are executing scripts with the same hash value at the same time, these scripts will be terminated.

      In addition, the Lua timeout period (config set lua-time-limit) cannot be configured. You can run SCRIPT KILL at any time to terminate the script, instead of waiting for the script to time out.

    • SCRIPT DEBUG

      Currently, the DEBUG command is not supported.

    • SCRIPT GET

      This command is added for querying scripts saved to a database with the SCRIPT LOAD command.

      The syntax is SCRIPT GET SHA1.

  3. Run Redis commands in Lua scripts.

    Similar to the open-source Redis, the Lua environment of GeminiDB Redis also provides a global Redis table to provide various functions for interacting with Redis Server.

    Table 1 shows the operations supported and not supported by GeminiDB Redis.

    Table 1 Function list

    Supported Operation

    Unsupported Operation

    • redis.call()
    • redis.pcall()
    • redis.sha1hex()
    • redis.error_reply()
    • redis.status_reply()
    • redis.log()
    • redis.LOG_DEBUG
    • redis.LOG_VERBOSE
    • redis.LOG_NOTICE
    • redis.LOG_WARNING
    • redis.replicate_commands()
    • redis.set_repl()
    • redis.REPL_NONE
    • redis.REPL_AOF
    • redis.REPL_SLAVE
    • redis.REPL_REPLICA
    • redis.REPL_ALL
    • redis.breakpoint()
    • redis.debug()
  4. Lua execution environment restrictions

    The open-source Redis has restrictions on the execution of Lua scripts, for example, restrictions on global variables, random function results, and system libraries and third-party libraries that can be used.

    GeminiDB Redis inherits most restrictions of the open-source Redis, but there are some differences in the following scenarios.

    • Write Dirty

      According to the open-source Redis specifications, if a write operation has been executed by a script, the script cannot be terminated by SCRIPT KILL. You must run SHUTDOWN NOSAVE to directly stop Redis Server.

      GeminiDB Redis does not support the SHUTDOWN command, so you can still run SCRIPT KILL to stop the script execution.

    • Random Dirty

      Due to the master/slave replication, the open-source Redis stipulates that if a script executes a command (Time or randomkey) to get a random key, the script cannot execute the command for writing semantics.

      The following Lua script is used as an example.

      local t = redis.call("time")
      return redis.call("set", "time", t[1]);

      When the execution of the script is transferred to the slave node, the time obtained by the Time command must be later than that obtained by the master node. Therefore, the value of the Set command executed on the slave node conflicts with that on the master node. The open-source Redis introduces replicate_commands to allow users to determine the behavior mode in this scenario.

      For GeminiDB Redis instances, there is no primary/standby relationship, and there is only one copy of data logically, so it is not limited by this restriction.

Forbidden Commands in the Lua Script

Hash commands: HSCAN.

List commands: BLPOP, BRPOP, and BRPOPLPUSH.

Set commands: SSCAN.

Sorted set commands: BZPOPMAX, BZPOPMIN, and ZSCAN.

Stream commands: XREAD and XREADGROUP.

Generic commands: RENAME, RENAMENX, RESTORE, SCAN, CLIENT, COMMAND, CONFIG, DBSIZE, FLUSHALL, FLUSHDB, INFO, and KEYS.

Lua commands: EVAL, EVALSHA, and SCRIPT.

Pub/sub commands: PSUBSCRIBE, PUBLISH, PUNSUBSCRIBE, SUBSCRIBE, and UNSUBSCRIBE.

Transactions commands: DISCARD, EXEC, MULTI, UNWATCH, and WATCH.