Jedis simple operation, Redis pipeline, Lua script and jedis simple example

1. Overall code example

public class JedisSingleTest {
    public static void main(String[] args) throws IOException {

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMinIdle(5);

        // Timeout, which is both a connection timeout and a read-write timeout. Starting from Jedis 2.8, there are constructors that distinguish connectionTimeout and soTimeout
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.231.131", 6379, 3000, null);

        Jedis jedis = null;
        try {
            //Take a connection from the redis connection pool and execute the command
            jedis = jedisPool.getResource();

            // Jedis direct operation
            /*System.out.println(jedis.set("ale", "cool"));
            System.out.println(jedis.get("ale"));*/

            // Pipe example
            /*Pipeline pl = jedis.pipelined();
            for (int i = 0; i < 10; i++) {
                pl.incr("aleKey");
                pl.set("ale" + i, "cool");
                // Analog pipeline error reporting
                pl.setbit("ale",-1,true);
            }
            List<Object> results = pl.syncAndReturnAll();
            System.out.println(results);*/

            //lua script simulates an atomic operation of reducing inventory of goods
            //Lua script command execution method: redis cli -- Eval / TMP / test.lua, 10
            jedis.set("product_count_10016", "15");  //Initialize inventory of item 10016
            String script = " local count = redis.call('get', KEYS[1]) " +
                            " local a = tonumber(count) " +
                            " local b = tonumber(ARGV[1]) " +
                            " b == 0 " +        //This line is wrong
                            " if a >= b then " +
                            "   redis.call('set', KEYS[1], a-b) " +
                            "   return 1 " +
                            " end " +
                            " return 0 ";
            Object obj = jedis.eval(script, Arrays.asList("product_count_10016"), Arrays.asList("10"));
            System.out.println(obj);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //Note that the connection is not closed here. In JedisPool mode, Jedis will be returned to the resource pool.
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

2. Jedis simple operation

2.1 core code

System.out.println(jedis.set("ale", "cool"));
System.out.println(jedis.get("ale"));

2.2 screenshot of Idea operation

The meaning of this code is to set the data of a string, and then take it out. We run it in Idea, as shown in the figure below:

2.3. Verify directly on Redis client

Then go to the built-in client authentication
As shown below, keys*

3. Redis Pipeline

In order to save the cost of network connection establishment and data transmission, we can use the pipeline method to put a group of operations into the pipeline and send them to the redis server for operation, which can save time.
However, there is also a disadvantage, that is, there is no atomic operation in the pipeline. After an error is reported in a command, it will continue to be executed.

3.1 core code

Pipeline pl = jedis.pipelined();
for (int i = 0; i < 10; i++) {
    pl.incr("aleKey");
    pl.set("ale" + i, "cool");
    // Analog pipeline error reporting
    pl.setbit("ale",-1,true);
}
List<Object> results = pl.syncAndReturnAll();
System.out.println(results);

3.2 screenshot of Idea operation

We will find that the error reported in each cycle will not affect the next cycle, as shown in the figure below:

3.3. Verify directly on Redis client

4. Redis Lua script

Redis launched the script function in 2.6, allowing developers to write scripts in Lua language and transfer them to redis for execution. The benefits of using scripts are as follows:
1. Reduce network overhead: batch commands can be passed in to operate, which is similar to pipeline.
2. Redis will execute the entire script as a whole and will not be inserted by other commands. The pipeline is not atomic, but the batch operation commands of redis (similar to mset) are atomic.
3. Replace redis's transaction function: redis's built-in transaction function is very weak, and error reporting does not support rollback. However, redis's lua script almost implements the conventional transaction function and supports error reporting and rollback. It is officially recommended that if you want to use redis's transaction function, you can use redis lua instead.

4.1. Execute Lua script on Redis client (I need to study it later, but I don't understand it)

The format is as follows:
EVAL script numkeys key [key ...] arg [arg ...]
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first seco nd
For example, in this line of code executed on the client, the preceding keys [1] and keys [2] are parameters, the following key1 and key2 are values, and the middle 2 represents two keys.

4.2. Java calls Redis Lua script

4.2.1 core code

jedis.set("product_count_10016", "15");  //Initialize inventory of item 10016
String script = " local count = redis.call('get', KEYS[1]) " +
                " local a = tonumber(count) " +
                " local b = tonumber(ARGV[1]) " +
                " if a >= b then " +
                "   redis.call('set', KEYS[1], a-b) " +
                "   return 1 " +
                " end " +
                " return 0 ";
Object obj = jedis.eval(script, Arrays.asList("product_count_10016"), Arrays.asList("10"));
System.out.println(obj);

4.2.2 screenshot of Idea operation

4.2.3. Verify directly on Redis client

On Redis's own client, we can see product_count_10016 is still its own initial value, indicating that the transaction is rolled back when an error is reported, as shown in the following figure:

4.3 shortcomings of Redis Lua script

Do not have dead loops and time-consuming operations in Lua script, otherwise redis will block and will not accept other commands. Therefore, pay attention to avoid dead loops and time-consuming operations. Redis is a single process, single thread execution script. The pipeline will block redis.

5. The above code reports an error and cannot operate Redis

To check the following points:

1. Check whether Redis is started
2. Check whether the linux firewall is turned off
Turn off the firewall: systemctl stop firewalld
3. Check whether the protected mode configuration in the redis.conf file is closed
Should be changed to: protected mode no
4. Check whether the flow is not closed after use
5. Comment out bind 127.0.0.1 in redis.conf file

Keywords: Java Redis lua

Added by DeathRipple on Thu, 21 Oct 2021 21:51:59 +0300