Redis Advanced Client Lettuce

Note for use: JDK8 and above are required, and the redis version is at least 2.6

Official document: https://lettuce.io/core/release/reference/index.html#getting-started.get-it

1. Introduction to Lettuce

Lettuce is a scalable thread-safe Redis client based on netty and Reactor. Lettuce provides synchronous, asynchronous, and reactive APIs to interact with Redis.

2. Basic use

When Lettuce is used, it mainly relies on the following four components:

① redisURI: connection information.
② redisClient: Redis client, if it is in cluster mode, there is a customized RedisClusterClient connected to the cluster.
③ connection: Redis connection.
④ redisCommands: Redis command API interface, which basically covers all the commands of the Redis release version, and provides synchronous (sync), asynchronous (async), and reactive (reative) invocation methods.

maven

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>

2.1 Stand-alone mode

2.1.1 Synchronization (sync)

Getting started case:

        /** 初始化四个组件 **/
        RedisURI redisUri = RedisURI.builder()
                .withHost("192.168.139.198")
                .withPort(6379)
                .withTimeout(Duration.of(10, ChronoUnit.SECONDS))
                .build();
        RedisClient redisClient = RedisClient.create(redisUri);
        StatefulRedisConnection<String, String> connection = redisClient.connect();
        RedisCommands<String, String> redisCommands = connection.sync();

        /** API的使用 **/
        String result = redisCommands.set("name", "gaojian");
        System.out.println(result);
        result = redisCommands.get("name");
        System.out.println(result);

        /** 关闭资源 **/
        connection.close();
        redisClient.shutdown();

The timeout period can be set through the following configuration

    SetArgs timeout = SetArgs.Builder.nx().ex(5);
    String result = redisCommands.set("name", "gaojian", timeout);

All connections inherit the default timeout from its RedisClient. The default timeout is 60 seconds. When a non-blocking command fails to return a result before the timeout expires, a RedisException is thrown, which can be changed in RedisClient or each connection (as above). If Redis responds incorrectly, the synchronous method will throw RedisCommandExecutionException, and the asynchronous connection will not throw an exception.

Redis connection is designed asLong-livedAnd it is thread-safe. If the connection is lost, it will reconnect until close() is called. After a successful reconnection, pending commands that have not timed out will be (re)sent, so at the end of the application, the connection is closed, and at the same time, the client instance is closed to release threads and resources.

2.1.2 Asynchronous (async)

Asynchronous methods can make better use of system resources instead of wasting threads waiting for network or disk I/O. You can make full use of threads to perform other work. Lettuce promotes asynchrony by building clients on Netty-based clients (multi-threaded, event-driven I/O frameworks). All communication is handled asynchronously.

        /** 初始化四个组件 **/
        RedisURI redisUri = RedisURI.builder()
                .withHost("192.168.139.198")
                .withPort(6379)
                .withTimeout(Duration.of(10, ChronoUnit.SECONDS))
                .build();
        RedisClient redisClient = RedisClient.create(redisUri);
        StatefulRedisConnection<String, String> connection = redisClient.connect();
        RedisAsyncCommands<String, String> asyncCommands = connection.async();

        /** API的使用 **/
        RedisFuture<String> future = asyncCommands.set("age", "18");
        future.get(10,TimeUnit.SECONDS);
        future.thenAccept(new Consumer<String>() {
    
    
            @Override
            public void accept(String value) {
    
    
                System.out.println(value);
            }
        });

        RedisFuture<String> redisFuture = asyncCommands.get("age");
        redisFuture.get(10,TimeUnit.SECONDS);
        redisFuture.thenAccept(new Consumer<String>() {
    
    
            @Override
            public void accept(String value) {
    
    
                System.out.println(value);
            }
        });

        /** 关闭资源 **/
        connection.close();
        redisClient.shutdown();

The call to the get() method (pull) will block the calling thread at least until the value is calculated, but in the worst case it will block the thread indefinitely. In order to prevent blocking the thread indefinitely, it is recommended to use timeout Configuration.

2.1.3 Responsive (reactor)

The author will not describe the method temporarily

2.2 Cluster mode

One or more initial seed nodes are required to connect to the Redis cluster. The complete cluster topology view (partition) is obtained on the first connection, so there is no need to specify all cluster nodes. Specifying multiple seed nodes helps to improve resiliency, because Lettuce can still connect to the cluster even if the seed node is unavailable.

Note: The cluster connection itself uses node connections to perform cluster operations. If a connection is blocked, all other users of the cluster connection may be affected.

2.2.1 Synchronization (sync)
        RedisURI node1 = RedisURI.create("192.168.139.172", 7000);
        RedisURI node2 = RedisURI.create("192.168.139.172", 7001);
        RedisURI node3 = RedisURI.create("192.168.139.172", 7002);
        RedisURI node4 = RedisURI.create("192.168.139.172", 7003);
        RedisURI node5 = RedisURI.create("192.168.139.172", 7004);
        RedisURI node6 = RedisURI.create("192.168.139.172", 7005);

        RedisClusterClient clusterClient =  RedisClusterClient.create(Arrays.asList(node1,node2,node3,node4,node5,node6));
        StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
        RedisAdvancedClusterCommands<String, String> clusterCommands = connection.sync();

        /** API的使用 **/
        String set = clusterCommands.set("name", "gaojian");
        System.out.println(set);

        String name = clusterCommands.get("name");
        System.out.println(name);

        connection.close();
        clusterClient.shutdown();
2.2.2 Asynchronous (async)
        RedisURI node1 = RedisURI.create("192.168.139.172", 7000);
        RedisURI node2 = RedisURI.create("192.168.139.172", 7001);
        RedisURI node3 = RedisURI.create("192.168.139.172", 7002);
        RedisURI node4 = RedisURI.create("192.168.139.172", 7003);
        RedisURI node5 = RedisURI.create("192.168.139.172", 7004);
        RedisURI node6 = RedisURI.create("192.168.139.172", 7005);

        RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1,node2,node3,node4,node5,node6));
        StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
        RedisAdvancedClusterAsyncCommands<String, String> asyncCommands = connection.async();

        /** API的使用 **/
        RedisFuture<String> future = asyncCommands.set("name", "gaojian");
        future.get(10,TimeUnit.SECONDS);
        future.thenAccept(new Consumer<String>() {
    
    
            @Override
            public void accept(String value) {
    
    
                System.out.println(value);
            }
        });

        RedisFuture<String> redisFuture = asyncCommands.get("name");
        redisFuture.get(10,TimeUnit.SECONDS);
        redisFuture.thenAccept(new Consumer<String>() {
    
    
            @Override
            public void accept(String value) {
    
    
                System.out.println(value);
            }
        });

        connection.close();
        clusterClient.shutdown();
2.2.3 Reaction (reactor)

The author will not describe the method temporarily

2.3 Connection pool

Lettuce connections are designed to be thread-safe, so a connection can be shared among multiple threads, and by default, Lettuce connections are automatically reconnected. In most cases, connection pooling is not needed, but Lettuce also supports connection pooling, which always brings complexity and maintenance costs.

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.4.3</version>
</dependency>
        RedisClusterClient clusterClient = RedisClusterClient.create(RedisURI.create("192.168.139.198", 6379));

        GenericObjectPool<StatefulRedisClusterConnection<String, String>> pool = ConnectionPoolSupport
                .createGenericObjectPool(() -> clusterClient.connect(), new GenericObjectPoolConfig());

        StatefulRedisClusterConnection<String, String> connection = pool.borrowObject();
        String age = connection.sync().set("age", "123");
        System.out.println(age);
        connection.sync().blpop(10, "age");

        String age1 = connection.sync().get("age");
        System.out.println(age1);

        pool.close();
        clusterClient.shutdown();

Guess you like

Origin blog.csdn.net/qq_44962429/article/details/113604673