preface

Ok,Have to know the Redis communication protocolI did not go into too much depth, because I think there is no need, good brothers can know how to connect to the client and request response is ok (too deep I will not). Today this is reasonable, good brothers should have used, unreasonable good brother read this will understandJedis. Reasonable good brothers and want to bar, this I played, don’t see it. No, no, no, no, no, no, no, no, no, no.

An overview of the

Jedis is a Java third party development package, which is the client of the Redis Java language. It is also the Java connection development tool recommended by Redis. Of course, this article is not the source code parsing (later will have, owe).

The source address

Jedis source

Source structure

What a lot of commands!!

Access to rely on

There are two common ways to obtain third-party development packages in Java:

  1. Download the target version directlyJedis-${version}.jarPackages are added to the project.
  2. Use integration build tools, for exampleMaven, gradle(Maven repository address) and so on willJedisThe configuration of the target version is added to the project.

Normal projects don’t use the first method unless they are very old. On the other hand, it’s basically Springboot projects now, so the second approach is usually used in real projects. If you don’t want to use this version of Maven, you can go to the above maven repository address and choose it yourself.

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>
Copy the code

On version selection, good brothers or can not be too playful. Because the Redis update speed is relatively fast, if the client can not keep up with the speed of the server, some features and bugs can not be updated in time, it is not conducive to daily development. Therefore, you should choose a stable version, that is, as stable as possible milestone version (don’t be like me, whichever people use more). In addition, choose to update the active third party development package, because the Redis upgrade will bring some new features, if the development package has not been supported by the provider will not be embarrassed, that is you embarrassed, change the third party package workload is a bit too much.

Basic usage

Using Jedis is as simple as the following three lines of code to implement the GET function. In addition, Jedis provides a variety of constructors that you can explore on your own

Early experience

public static void main(String[] args) {
        // 1. Obtain a Jedis object whose final host and port are the IP address and port number of the Jedis server
        Jedis jedis = new Jedis("127.0.0.1".6379);
        // 2. Set the password (this step is not required if no password is configured)
        jedis.auth("123456");
        // 3. Jedis execute get, value="world"
        String value = jedis.get("hello");
    }
Copy the code

The above method is just for demonstration. In actual projects, it is recommended to use try catch finally to write the code: on the one hand, when Jedis has an exception (itself a network operation), the exception can be caught or thrown; On the other hand, it is a good practice to close a Jedis connection during development, whether the execution succeeds or fails. This code looks something like this:

public static void main(String[] args) {
        Jedis jedis = null;
        try {
            jedis = new Jedis("127.0.0.1".6379);
            jedis.get("hello");
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if(jedis ! =null) { jedis.close(); }}}Copy the code

Here are a few simple examples of the five commonly used data structure-related methods

public static void main(String[] args) {
        Jedis jedis = null;
        try {
            jedis = new Jedis("127.0.0.1".6379);
            // 1.string Output result: OK
            jedis.set("hello"."world");
            // Output result: world
            jedis.get("hello");
            // Output: 1
            jedis.incr("counter");
            // 2.hash
            jedis.hset("myhash"."f1"."v1");
            jedis.hset("myhash"."f2"."v2");
            {f1=v1, f2=v2}
            jedis.hgetAll("myhash");
            // 3.list
            jedis.rpush("mylist"."1");
            jedis.rpush("mylist"."2");
            jedis.rpush("mylist"."3");
            [1, 2, 3]
            jedis.lrange("mylist".0, -1);
            // 4.set
            jedis.sadd("myset"."a");
            jedis.sadd("myset"."b");
            jedis.sadd("myset"."a");
            [b, a]
            jedis.smembers("myset");
            // 5.zset
            jedis.zadd("myzset".99."tom");
            jedis.zadd("myzset".66."peter");
            jedis.zadd("myzset".33."james");
            / / output: [33.0] [[" James "], and [[" Peter "], 66.0], [[" Tom "], 99.0]]
            jedis.zrangeWithScores("myzset".0, -1);
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if(jedis ! =null) { jedis.close(); }}}Copy the code

serialization

In our normal development, there are some scenarios where we need to store a Java object into Redis. Jedis itself does not provide serialization tools, which means that developers need to introduce their own serialization tools. There are many serialization tools, such as XML, Json, Google’s Protobuf, Facebook’s Thrift, and so on. The choice of serialization tools is up to the developer. The following uses Protostuff (Java client for Protobuf) as an example.

  1. Add Maven dependencies for Protostuff
<protostuff.version>1.6.0</protostuff.version>
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>${protostuff.version}</version>
</dependency>
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>${protostuff.version}</version>
</dependency>
Copy the code
  1. Defining entity Classes
@Data
public class User implements Serializable {
    public User(a) {}public User(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    / / number
    private Long id;
    / / name
    private String name;
    / / age
    private int age;
}
Copy the code
  1. Serialization utility classProtostuffSerializerProvides methods for serialization and deserialization, which I wrote down hereUserClass, good brothers can optimize
/** * serialization tool */
public class ProtostuffSerializer {
    private Schema<User> schema = RuntimeSchema.createFrom(User.class);

    public byte[] serialize(final User user) {
        final LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            return serializeInternal(user, schema, buffer);
        } catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally{ buffer.clear(); }}public User deserialize(final byte[] bytes) {
        try {
            User user = deserializeInternal(bytes, schema.newMessage(), schema);
            if(user ! =null) {
                returnuser; }}catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        return null;
    }

    private <T> byte[] serializeInternal(final T source, final Schema<T>
            schema, final LinkedBuffer buffer) {
        return ProtostuffIOUtil.toByteArray(source, schema, buffer);
    }

    private <T> T deserializeInternal(final byte[] bytes, final T result, final
    Schema<T> schema) {
        ProtostuffIOUtil.mergeFrom(bytes, result, schema);
        return result;
    }
Copy the code
  1. Results of the test
public static void main(String[] args) {
        Jedis jedis = null;
        try {
            ProtostuffSerializer serializer = new ProtostuffSerializer();
            User user = new User(1L."Lisi".18);
            // Serialize the user object
            byte[] userByte = serializer.serialize(user);
            byte[] key = "User:1".getBytes();
            jedis = new Jedis("127.0.0.1".6379);
            // Store user objects
            jedis.set(key, userByte);
            // Get the user object
            byte[] resultByte = jedis.get(key);
            // deserialize
            User userResult = serializer.deserialize(resultByte);
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if(jedis ! =null) { jedis.close(); }}}Copy the code

Connection pool usage

All of the above is the direct connection model,JedisIt’s going to be new every timeTCPIt is obviously not efficient to use Redis frequently. The principle of this method is shown in the following figure

Pooling is a common programming technique. It can significantly optimize application performance and reduce the resource cost of frequent system connections when there are a large number of requests. Common in our daily work are database connection pool, thread pool, object pool and so onexpensivetime-consumingResources maintained in a specificThe pool, the minimum number of connections, maximum number of connections, blocking queue and other configurations are specified to facilitate unified management and reuse. Usually, it also has some supporting functions such as probe mechanism, forced recovery and monitoring.JedisprovidesJedisPoolThis class acts as a pairJedisThe connection pool is also usedApacheThe generic object pooling tool forCommon - in the poolA resource management tool. The schematic diagram is as follows:

Pooling versus direct connection

The client connects to Redis usingTCPProtocol, direct connection mode each time need to be establishedTCPConnection, and connection pooling is a way that can be pre-initializedJedisConnect, so each time only fromJedisThe connection pool is borrowed, and the borrow and return operations are done locally, with a small concurrent synchronization overhead, much less than new creationTCPConnection overhead. In addition, the way of direct connection cannot be limitedJedisThe number of objects may cause connection leakage in extreme cases, and the form of connection pool can effectively protect and control resource usage.

Connection Pool Example

Jedis provides the JedisPool class as a connection pool for Jedis, and uses Apache’s common object pool tool as a resource management tool. When building a connection pool object, you need to provide a configuration object for the pool object, along with JedisPoolConfig(inherited from GenericObjectPoolConfig). We can use this configuration object to configure connection pool parameters (such as the maximum number of connections, the maximum number of empty connections, etc.).

/** * omit try-catch-finally **@param args
 */
public static void main(String[] args) {
    // Pooled configuration, attributes are not detailed
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxIdle(8);
    config.setMaxTotal(18);
    // instantiate a connection pool
    JedisPool pool = new JedisPool(config, "127.0.0.1".6379.2000);
    // Get a connection
    Jedis jedis = pool.getResource();
    / / get the value
    String value = jedis.get("hello");
    System.out.println(value);
}
Copy the code

Basic attributes are shown below:

Pipeline using

There is a good brother who is not familiar with Pipeline, it doesn’t matter, I have prepared for you here. Read Redis Pipeline this is enough, really enough. Jedis supports Pipeline, we know that Redis provides the mGET, mset method, but does not provide the mdel method, if you want to implement this function, you can use Pipeline to simulate batch delete, although it is not an atomic command like mGET and mset. But it can be used in most scenarios.

/** * omit try-catch-finally *@param args
 */
public static void main(String[] args) {
    List<String> keys = Lists.newArrayList();
    keys.add("hello");
    keys.add("test");
    Jedis jedis = new Jedis("127.0.0.1");
    // 1. Generate the pipeline object
    Pipeline pipeline = jedis.pipelined();
    // 2. Pipeline executes the command (add to the command group)
    for (String key : keys) {
        pipeline.del(key);
    }
    // 3. Run the command
    pipeline.sync();
}
Copy the code

Use Lua

What, good brothers have not used Lua, see Redis long text Lua explain fill up the lesson (you see, all say those things before the foundation, call you bad good-looking). Executing Lua under Jedis is similar to executing Lua in Redis-CLI. The following contains two ways of executing Lua

/** * omit try-catch-finally **@param args
  */
 public static void main(String[] args) {
     // Pooled configuration, attributes are not detailed
     JedisPoolConfig config = new JedisPoolConfig();
     config.setMaxIdle(8);
     config.setMaxTotal(18);
     // instantiate a connection pool
     JedisPool pool = new JedisPool(config, "127.0.0.1".6379.2000);
     // Get a connection
     Jedis jedis = pool.getResource();
     String key = "hello";
     String script = "return redis.call('get',KEYS[1])";
     1. Execute a script directly
     Object eval = jedis.eval(script, 1, key);
     // Load a script into Redis
     String scriptSha = jedis.scriptLoad(script);
     // 2. Execute the script
     Object evalsha = jedis.evalsha(scriptSha, 1, key);
     System.out.println(evalsha.toString());
 }
Copy the code

conclusion

This article still does not talk too deep just point, all is to say some APIS provided by Jedis, although it is not difficult, but it is necessary to practice in order to remember more deeply, good brothers or don’t be lazy oh. In addition, the following points need to be noted when using Jedis:

  1. JedisOperations need to be placedtry catch finallyIs more reasonable.
  2. The difference between the above direct connection and pooling needs to be understood clearly. Normally, pooling will be used for this technology.
  3. The individual properties of the connection pool vary depending on the server configuration.
  4. ifkeyandvalueByte arrays are involved, and you need to choose the appropriate serialization method.
  5. This article is missing a reference toJedisCases related to Redis high availability (Sentinel and cluster mode).

That’s the end of this issue. Welcome to leave your comments in the comments sectionAsk for attention, ask for likes

Redis communication protocol you have to know