Why Redis requires support for LUA scripting
When the application requires Redis to complete some features that are not supported by Redis commands, either extend the Redis client or even write C extension redis server. This greatly makes the implementation of the application difficult. Based on this, Redis's built-in LUA interpreter enables REDIS client to initiate a LUA script to fulfill special functional requirements.
Using LUA scripts in Redis
Support for executing LUA can be provided in Redis by using the eval and Evalsha commands.
Eval syntax:
EVAL script Numkeys key [key ...] arg [arg ...]
- Script is Lua scripting;
- Numkeys is the number of keys in a LUA script;
- Key is multi-select, that is, the Lua script can operate multiple keys;
- Arg is a multi-select that provides parameters for Lua's basic execution;
Key and Arg can be obtained through the global variables keys and argv in the Lua script. KEYS and argv are arrays, keys[1],keys[2], ... Wait, the cardinality starts at 1 and gets the following key in order. argv.
Such as:
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
The above returns the value of Key1 and Key2, and returns a single parameter.
Redis provides two different LUA function calls to execute a redis command:
- Redis.call (): An error will be returned when the Redis command executes an error;
- Redis.pcall: When the Redis command executes an error, an exception is caught and a LUA table with the wrong field is returned;
Such as:
127.0.0.1:6380> lpush foo a
(integer) 1
127.0.0.1:6380> eval "return redis.call(‘get‘,‘foo‘)" 0
(error) ERR Error running script (call to f_6b1bf486c81ceb7edf3c093f4c48582e38c0e791): @user_script:1: WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6380> EVAL "return redis.pcall(‘get‘, ‘foo‘)" 0
(error) WRONGTYPE Operation against a key holding the wrong kind of value
The Lua script, as a scripting language, has its own data type, and Redis has its own data type. When you switch between LUA scripts and Redis command operations, you inevitably involve conversions of data types.
Conversions between data types follow a design principle: when Redis invokes the LUA interpreter to execute a script, the Redis type is converted to the LUA type, and when the Lua script executes, the return value is converted to the Redis type, and then the LUA script is returned to the client by Eval.
Specific correspondence details Reference: conversion between Lua data types and Redis data types.
Benefits of Lua Scripting in Redis
Atomicity: Redis uses a single LUA interpreter to run all scripts, and Redis guarantees that the script will execute atomically: When a script is running, no other scripts or Redis commands are executed. This is similar to a transaction surrounded by multi/exec. In other clients ' view, the effect of the script is either invisible or completed. On the other hand, this also means that it is not a good idea to execute a slow-running script. It is not difficult to write a script that runs very quickly and Shunliu, because the script has very little overhead, but be careful when you have to use some slow-running scripts, because when these snail scripts run slowly, other clients cannot execute the command because the server is busy.
Cache script: The eval command requires that a LUA script be sent to the server each time a LUA script is executed, although the Redis caching mechanism guarantees that LUA scripts will not be recompiled, but each time the script body is transferred, it is no doubt that the frame is consumed. To reduce the band, Redis launches the Lua script using the Evalsha command, but the first parameter of Evalsha is not the Lua script, but the Shasum checksum value corresponding to the script.
Such as:
127.0.0.1:6380> set foo bar
OK
127.0.0.1:6380>
127.0.0.1:6380>
127.0.0.1:6380> eval "return redis.call(‘get‘,‘foo‘)" 0
"bar"
127.0.0.1:6380> evalsha 6b1bf486c81ceb7edf3c093f4c48582e38c0e791 0
"bar"
The underlying implementation of the client library can always be optimistic about using Evalsha instead of EVAL, and expects the script to be used to be saved on the server, using the EVAL command to resend the script only when the NOSCRIPT error occurs, so that bandwidth can be saved to a maximum.
The script command provided by Redis
- Script Flush: Clears all script caches;
- Script exists: Determine if the script exists based on the given script checksum;
- Script Load: Loads a script into memory, but does not run;
- Script kill: Kills a scripted program that is executing;
Reference
Https://redis.io/commands/eval
Support for Redis (vi) LUA scripting