Development idea of using Lua script in Redis
Redis provides the eval command to execute the Lua script. The following example shows how to execute a Lua script on the Redis server.
1. Run the following commands to execute the Lua script:
Command Format |
Description |
One of the methods corresponding to the Jedis object on the Jedis client (more overload methods are available) |
EVAL script numkeys key [key...] arg [arg...] |
Execute Lua script |
Public Object eval (String script, int keyCount, String... params) |
EVALSHA sha1 numkeys key [key...] arg [arg...] |
Evaluate the script cached on the server based on the given sha1 Verification Code |
Public Object evalsha (String sha1, int keyCount, String... params) |
Script load script |
Cache the given script without executing it, and return the sha1 check value. |
Public String scriptLoad (String script) |
Script exists sha1 [sha1...] |
Given the SHA1 checksum of one or more scripts, a list containing 0 and 1 is returned, indicating whether the script specified by the checksum has been saved in the cache. |
Public List <Boolean> scriptExists (String... sha1) |
SCRIPT FLUSH |
Clear all Lua script caches |
|
SCRIPT KILL |
Kill the currently running Lua script. This command takes effect only when it has not executed any write operations (if the write operation has been executed, you need to use the shutdown nosave command to process it) |
2. Run the Lua script through the redis-cli client.
Redis-cli -- eval myscript. lua key1 key2, arg1 arg2 arg3
Note that keys and parameters are separated by commas, which is different from executing the evel command in interactive mode.
3. Actual cases
Scenario 1: a specific request can be accessed only 10 times in one second. If the request meets the access conditions, True is returned. Otherwise, False is returned.
The Java client operates the Redis service and the implementation code is as follows:
/**
* Access Control
*
* A maximum of 10 accesses can be made within one second.
*
* @ Param key
* @ Return
*/
Public boolean isAccess (String key ){
String rkey = "acc:" + key;
Long value = jedis. incr (rkey );
If (value = 1 ){
Jedis. expire (rkey, 1 );
Return true;
} Else {
Boolean rs = value <= 10;
Return rs;
}
}
The INCR command is used as a counter. If rkey exists, 1 is added and the final value is returned. Otherwise, the initialization value is 0 and 1 is added. In the preceding procedure, if the accessed rkey does not exist, it indicates the first request. In this case, set the expiration time for its rkey to 1 second. Otherwise, compare whether its value exceeds the threshold value of the specified number of requests by 10.
Use the Lua script to complete this operation:
--[[
Judge status
KEYS [1]: key
ARGV [1]: request numbers
ARGV [2]: expires times seconds
--]
Local key, rqn, exp = KEYS [1], ARGV [1], ARGV [2];
Local value = redis. call ("incr", key );
Redis. log (redis. LOG_NOTICE, "incr"... key );
If (tonumber (value) = 1) then
Redis. call ("expire", key, exp );
Redis. log (redis. LOG_NOTICE, "expire"... key... ""... exp)
Return true;
Else
Return tonumber (value) <= tonumber (rqn );
End
Java client code has certain defects in implementing this function. For example, one incr and expire commands need to be operated every one second, and this command is initiated by the client through the network, the use of Lua scripts ensures the atomicity of operations, and allows each operation to complete corresponding judgment operations on the server with only one key. The script load can be used to cache the SCRIPT to the server. The sha1 check value + parameter (Key, ARG) can be used for execution to reduce network transmission and better encapsulate this function.
Scenario 2: Batch Delete mode keys
Currently, the DELETE command del provided by redis only supports deleting a specified number of keys, and cannot be deleted by specifying the mode key. For example, del * user deletes the key ending with a user.
The keys command is provided in redis. You can use the specified mode key to obtain the key List. The following command uses the keys and del commands to delete keys in a specified mode in batches.
--[[
Pattern delete key
KEYS [1]: pattern
--]
Redis. log (redis. LOG_NOTICE, "call keys" .. KEYS [1]);
Local keys = redis. call ("keys", KEYS [1]);
Local count = 0;
If (keys and (table. maxn (keys)> 0) then
For index, key in ipairs (keys) do
Redis. log (redis. LOG_NOTICE, "del"... key );
Count = count + redis. call ("del", key );
End
End
Return count;
It should be noted that scenario 2 can be used as an idea to use Lua scripts combined with redis built-in commands to implement specific function commands. The Mode key batch deletion here does not provide a good command, because if the number of keys is large, there will be serious performance problems. Redis limits the Lua script execution time to a maximum of 5 seconds by default. If it exceeds 5 seconds, it will continue to accept requests from the client and simply return the BUSY result. At this time, the script kill or shutdown nosave command is required for corresponding processing. Therefore, we should try our best to ensure extremely fast script execution.
Scenario 3: generate a random number
For Redis, scripts are executed in the same dataset and the write commands are consistent under the same parameters. It does not depend on the implicit dataset. The status changes during different execution periods during script execution are not dependent on the input of external I/O devices.
To meet the script conditions executed by the Redis service, pay attention to a lot of places, you can see: http://redis.io/commands/eval
The following is a Lua script that implements the random number list:
--[[
Random lpush a list key-value
KEYS [1]: key name
ARGV [1]: ramdom seed value
ARGV [2]: add element count
--]
Math. randomseed (ARGV [1]);
For I = 1, ARGV [2], 1 do
Redis. call ("lpush", KEYS [1], math. random ());
End
Redis. log (redis. LOG_NOTICE, "lpush" .. KEYS [1]);
Return true;
The preceding script changes the parameters of the randomseed function to implement a random number. If the ARGV [1] parameter values are the same when the preceding script is executed twice, the random number is the same.
Execute the above script to record the value of each production, delete the corresponding key, and generate again.
Compared with the above results, when executing this script, the generation of random numbers is determined by the seed parameter (the first parameter.
The random numbers generated under the same random number seed are the same. If you execute the script again and specify the number of random numbers to be generated n is less than the number of random numbers to be generated m, take the first n generated, if the number of the specified random numbers n is greater than the number of generated random numbers m, the number of random numbers (n-m) is generated and fixed.
4. Summary of using Lua scripts in Redis
Redis has a built-in Lua interpreter, which provides great flexibility for operating Redis servers and data.
These scenarios are not practical and effective, but they do not cover up the possibility that the combination of Lua and Redis will provide more imagination and operation space for Redis.
We can use Lua to implement more commands with specific functions; Use Lua to encapsulate businesses with complicated Redis operations; count, statistics, analysis, and data collection; and implement business operation transaction control. More scenarios require constant exploration and experimentation.
Install and test Redis in Ubuntu 14.04
Redis cluster details
Install Redis in Ubuntu 12.10 (graphic explanation) + Jedis to connect to Redis
Redis series-installation, deployment, and maintenance
Install Redis in CentOS 6.3
Learning notes on Redis installation and deployment
Redis. conf
Redis details: click here
Redis: click here
This article permanently updates the link address: