Redis provides the use of the eval command to execute LUA scripts. Here are a few small examples of how to execute LUA scripts on the Redis server side.
1. Several commands to execute the LUA script are as follows:
Command format |
Description |
One of the methods that corresponds to the Jedis client Jedis object (there are more overloaded methods) |
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 ...] |
Evaluates the script cached in the server based on the given SHA1 checksum code |
Public Object Evalsha (string sha1, int keycount, string ... params) |
Script LOAD Script |
Caches the given script, does not execute, and returns the SHA1 checksum value |
public string Scriptload (String script) |
SCRIPT EXISTS SHA1 [SHA1 ...] |
Given the SHA1 checksum of one or more scripts, returns a list of 0 and 1 indicating whether the checksum specified script has been saved in the cache |
Public list<boolean> scriptexists (String ... sha1) |
SCRIPT FLUSH
|
Clear all Lua script caches |
|
SCRIPT KILL |
Kills the currently running Lua script, which takes effect only if the script has not performed any write operations (if a write has already been performed, it needs to be handled by the Shutdown nosave command) |
|
2. Execute LUA scripts via REDIS-CLI client
REDIS-CLI--eval Myscript.lua key1 key2, arg1 arg2 arg3
It is important to note that a comma is used to separate keys and parameters, which differs from executing the EVEL command in interactive mode.
3. Actual cases
Scenario One: Only 1 seconds for a particular request is allowed to access 10 times, and returns True when the request access condition is met, otherwise false is returned.
The Java client operates the Redis service and implements the following code:
/** * Access control * up to 10 times in 1 seconds * * @param key * @return */public boolean isaccess (String key) {string rkey = "ACC:" + Key;lo ng value = JEDIS.INCR (Rkey), if (value = = 1) {Jedis.expire (Rkey, 1); return true;} else {Boolean rs = value <= 10;return RS;}}
The INCR command acts as a counter, and if rkey exists, it increases by 1 to return the final value, otherwise the initialization value is 0 and then 1. As in the program, if Access Rkey does not exist, it represents the first request, at which time the Rkey setting expires at 1 seconds, otherwise the value is more than the threshold of the number of requests to establish 10.
Use a LUA script to do this:
--[[judge status Keys[1]:keyargv[1]:request numbersargv[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
There are some drawbacks to this functionality through Java client code, such as the need to operate 1 incr and expire commands every 1 seconds, and the command is initiated by the client over the network, while the use of LUA scripts can guarantee the atomicity of the operation. It also makes it possible for each operation to require only one key to perform the appropriate judgment on the server side. Script load can be cached to the server, through the SHA1 checksum value + parameters (Key,arg) to perform, reduce network transmission, but also for the function of a better encapsulation.
Scenario Two: Specify Mode key Bulk Delete
The Delete command del currently provided by Redis only supports the deletion of a specified number of keys and cannot be deleted by specifying the mode key, for example: Del *user delete the key that ends with the user.
The keys command is available in Redis, which allows you to get a list of keys by specifying the mode key, which implements a command for bulk deletion of a specified mode key by combining the keys and Del commands.
--[[pattern Delete keykeys[1]:p attern--]]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); Endendreturn count;
It is important to note that scenario two can be used as a way of thinking by combining the Redis built-in commands to implement commands for specific functions through LUA scripting. And here the Mode key bulk Delete is not a good command, because if the number of key is very large, there will be more serious performance problems. Redis default limit Lua script execution time is 5 seconds, if more than 5 seconds will continue to accept requests from the client, and simply return the busy results. In this case, the script kill or shutdown Nosave command is required to do the corresponding processing. Therefore, you should try to ensure that the script executes very quickly.
Scenario three: Generating random numbers
For Redis Also, script execution is consistent across the same data set and execution of write commands under the same parameters. It is independent of the implicit data set, the state changes during the execution of the script during different execution times, and does not rely on input from external I/O devices.
To conform to the scripting conditions performed by the Redis service, there are a number of places to be aware of, see: Http://redis.io/commands/eval
The following is a LUA script that implements a random list of numbers:
--[[random Lpush a list key-valuekeys[1]:key nameargv[1]:ramdom seed valueargv[2]:add element Count--]]math.randomseed ( ARGV[1]); for I=1, argv[2], 1 do redis.call ("Lpush", Keys[1], math.random ()); Endredis.log (Redis. Log_notice, "Lpush". KEYS[1]); return true;
The above script implements the random number by changing the parameters of the Randomseed function, and if the above script is executed two times, the argv[1] parameter value is the same, the resulting random number is the same.
By executing the above script, the value of each production is recorded, then the corresponding key is deleted and generated again.
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5B/FC/wKioL1UYz4WSgIhaAAOqB1w19Sc305.jpg "style=" float: none; "title=" Randomlist.png "alt=" Wkiol1uyz4wsgihaaaoqb1w19sc305.jpg "/>
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5C/01/wKiom1UYzkqx3NzwAAFpvCYWbRo501.jpg "style=" float: none; "title=" Randomlist2.png "alt=" Wkiom1uyzkqx3nzwaafpvcywbro501.jpg "/>
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/5C/02/wKiom1UYz6DwtZZyAAJG2oORc7c681.jpg "title=" Randomlist3.png "alt=" Wkiom1uyz6dwtzzyaajg2oorc7c681.jpg "/>
Comparing the results above, the generation of random numbers is determined by the seed parameter (the first parameter) when the script is executed.
The random number generated under the same random number seed is the same, if the script is executed again, specifying that the generated random number of n is less than the number of random number m generated, then take the first n generated, if the specified generated random number n is greater than the number of random number m generated, the number is regenerated to (N-M) a random number, and fixed down.
Summary of using LUA scripts in 4.Redis
Redis has built-in LUA interpreters, which provides great flexibility for operating Redis servers and data.
Some of the scenarios are not practical and effective, but they do not obscure that the combination of LUA and Redis will provide greater imagination and operational space for Redis's use.
We can implement commands for more specific functions through LUA, and use Lua to encapsulate complex redis operations, count, statistics, analyze, collect data, implement business operations transaction control, and more. More scenes, but also in practice to constantly explore and try.
This article from "Mustang Red" blog, reproduced please contact the author!
The idea of using LUA scripts in Redis