Redisson lua

Redis supports atomic operations using Lua scripts, and Redisson provides an RScript interface for executing Lua scripts, as well as an implementation class, RedissonScript.

1. API Examples:

RedissonScript.eval(Mode mode, String luaScript, ReturnType returnType, List keys, Object… values); Lua scripts can receive KEYS and values with KEYS and ARGV arrays (both of which start at 1). Note that value is serialized (not RScript ARGV, which redisson serializes when stored).

2. Redisson serialization feature

Suppose you have a hash structure where the key is room, the field is roomId, and the value is {roomId} of type Long. Then the field and value structures in Redis can be observed by writing through the Redisson API, as shown in the figure below:

In particular, in the diagramThe opening and closing double quote characters and backslashes do not exist in the actual field and valueThis is only shown through redis CLI query.

In fact, field in Redis is:

"roomId"
Copy the code

The value is:

["java.lang.Long", 123456]Copy the code

The two values in brackets [] indicate the type and value of value respectively.

3. Script example

Example 1 :(1) use KEYS and ARGV arrays in lua, and (2) construct serialized values in lua

  • Only key is not serialized by Redisson. Field and value are serialized in various data structures.

The following code shows how to write and read hash structures using lua scripts. Key is roomId, field is roomId, value is 123456 (java.lang.Long,123456).

@Test
public void testLuaScript() {
    RedissonClient redissonClient = redissonService.redissonClient();
    RScript rScript = redissonClient.getScript();
    Long roomId = 123456L;
   String hsetRoomId = "redis.call('HSET', KEYS[1], ARGV[1], ARGV[2]);" +
                "return redis.call('HGET', KEYS[1], '\"roomId\"');";
    Long result = rScript.eval(RScript.Mode.READ_WRITE, hsetRoomId, RScript.ReturnType.INTEGER,
            Lists.newArrayList("room"),
            Lists.newArrayList("roomId", roomId).toArray());
    Assert.assertTrue(roomId.equals(result));
}
Copy the code

The first line of the Lua script, which writes using ARGV[1] as a field, and the second line, which reads using a Lua string as a field, verify that Lua serializes at storage.

  • Note that the second line of lua script contains extra backslashes for escape.

Example 2: Processing the obtained value in Lua

The lua script gets the serialized value and processes it. Since I’m not good at Lua scripting and don’t know if Lua can use any JSON libraries in Redisson, I simply used Lua’s string API. Examples of handling code:

local roomId = string.sub(roomIdJson, string.find(roomIdJson, ', ') + 1, string.len(roomIdJson) - 1);
Copy the code

Test code:

@Test
public void testLuaScript2() { Long roomId = 123456L; // Prepare data structure: (1) Store roomId, key = room, field = roomId, value = 123456 // The value as a string array object redisService. HsetWithThrow ("room"."roomId", roomId, true);
    redisService.setWithThrow("roomId.123456", Lists.newArrayList("Jack"."Rose"));

    RedissonClient redissonClient = redissonService.redissonClient();
    RScript rScript = redissonClient.getScript();
    String getRoomUserList =
            // roomIdJson = ["java.lang.Long", 123456]"local roomIdJson = redis.call('HGET', KEYS[1], '\"roomId\"'); " +
            "local roomId = " +
            " string.sub(roomIdJson, string.find(roomIdJson, ',') + 1, string.len(roomIdJson) - 1); " +
            "return redis.call('GET', 'roomId' .. '.' .. roomId); ";
    ArrayList result = rScript.eval(RScript.Mode.READ_WRITE, getRoomUserList, RScript.ReturnType.VALUE,
            Lists.newArrayList("room"),
            new Object[0]);
    Assert.assertTrue(result.contains("Jack"));
}
Copy the code