Lettuce 指南

将 Lettuce 应用程序连接到 Redis 数据库

安装 Redis 和 Redis 客户端,然后将 Lettuce 应用程序连接到 Redis 数据库。

Lettuce

Lettuce 通过异步和响应式 API 提供了一种功能强大且高效的方式与 Redis 交互。通过利用这些功能,你可以构建高性能、可扩展的 Java 应用程序,充分利用 Redis 的功能。

安装

若要将 Lettuce 作为依赖项包含在应用程序中,请按如下所示编辑相应的依赖项文件。

如果你使用 Maven,请将以下依赖项添加到你的 pom.xml

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.3.2.RELEASE</version> <!-- Check for the latest version on Maven Central -->
</dependency>

如果你使用 Gradle,请将此行包含在你的 build.gradle 文件中

dependencies {
    compile 'io.lettuce:lettuce-core:6.3.2.RELEASE
}

如果你希望直接使用 JAR 文件,请从 Maven Central 或任何其他 Maven 存储库下载最新的 Lettuce,以及可选的 Apache Commons Pool2 JAR 文件。

若要从源代码构建,请参阅 Lettuce 源代码 GitHub 存储库 上的说明。

连接

首先创建一个到 Redis 服务器的连接。使用 Lettuce 有多种方法可以实现此目的。以下列出几种方法。

异步连接

package org.example;
import java.util.*;
import java.util.concurrent.ExecutionException;

import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;

public class Async {
  public static void main(String[] args) {
    RedisClient redisClient = RedisClient.create("redis://localhost:6379");

    try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
      RedisAsyncCommands<String, String> asyncCommands = connection.async();

      // Asynchronously store & retrieve a simple string
      asyncCommands.set("foo", "bar").get();
      System.out.println(asyncCommands.get("foo").get()); // prints bar

      // Asynchronously store key-value pairs in a hash directly
      Map<String, String> hash = new HashMap<>();
      hash.put("name", "John");
      hash.put("surname", "Smith");
      hash.put("company", "Redis");
      hash.put("age", "29");
      asyncCommands.hset("user-session:123", hash).get();

      System.out.println(asyncCommands.hgetall("user-session:123").get());
      // Prints: {name=John, surname=Smith, company=Redis, age=29}
    } catch (ExecutionException | InterruptedException e) {
      throw new RuntimeException(e);
    } finally {
      redisClient.shutdown();
    }
  }
}

参考指南 中了解有关异步 Lettuce API 的更多信息。

响应式连接

package org.example;
import java.util.*;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;

public class Main {
  public static void main(String[] args) {
    RedisClient redisClient = RedisClient.create("redis://localhost:6379");

    try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
      RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

      // Reactively store & retrieve a simple string
      reactiveCommands.set("foo", "bar").block();
      reactiveCommands.get("foo").doOnNext(System.out::println).block(); // prints bar

      // Reactively store key-value pairs in a hash directly
      Map<String, String> hash = new HashMap<>();
      hash.put("name", "John");
      hash.put("surname", "Smith");
      hash.put("company", "Redis");
      hash.put("age", "29");

      reactiveCommands.hset("user-session:124", hash).then(
              reactiveCommands.hgetall("user-session:124")
                  .collectMap(KeyValue::getKey, KeyValue::getValue).doOnNext(System.out::println))
          .block();
      // Prints: {surname=Smith, name=John, company=Redis, age=29}

    } finally {
      redisClient.shutdown();
    }
  }
}

参考指南 中了解有关响应式 Lettuce API 的更多信息。

Redis 集群连接

import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands;

// ...

RedisURI redisUri = RedisURI.Builder.redis("localhost").withPassword("authentication").build();

RedisClusterClient clusterClient = RedisClusterClient.create(redisUri);
StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
RedisAdvancedClusterAsyncCommands<String, String> commands = connection.async();

// ...

connection.close();
clusterClient.shutdown();

TLS 连接

在部署应用程序时,请使用 TLS 并遵循 Redis 安全指南

RedisURI redisUri = RedisURI.Builder.redis("localhost")
                                 .withSsl(true)
                                 .withPassword("secret!") // use your Redis password
                                 .build();

RedisClient client = RedisClient.create(redisUri);

Lettuce 中的连接管理

Lettuce 使用 ClientResources 来高效管理共享资源,如事件循环组和线程池。对于连接池,Lettuce 利用 RedisClientRedisClusterClient,它们可以高效地处理多个并发连接。

使用 Lettuce 的典型方法是创建一个 RedisClient 实例并重复使用它来建立与 Redis 服务器的连接。这些连接是多路复用的;也就是说,可以在单个或少量连接上并发运行多个命令,从而降低了显式池化的重要性。

Lettuce 提供了与 Lettuce 异步连接方法一起使用的池配置。

package org.example;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.TransactionResult;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.StringCodec;
import io.lettuce.core.support.*;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

public class Pool {
  public static void main(String[] args) {
    RedisClient client = RedisClient.create();

    String host = "localhost";
    int port = 6379;

    CompletionStage<BoundedAsyncPool<StatefulRedisConnection<String, String>>> poolFuture
        = AsyncConnectionPoolSupport.createBoundedObjectPoolAsync(
            () -> client.connectAsync(StringCodec.UTF8, RedisURI.create(host, port)),
            BoundedPoolConfig.create());

    // await poolFuture initialization to avoid NoSuchElementException: Pool exhausted when starting your application
    AsyncPool<StatefulRedisConnection<String, String>> pool = poolFuture.toCompletableFuture()
        .join();

    // execute work
    CompletableFuture<TransactionResult> transactionResult = pool.acquire()
        .thenCompose(connection -> {

          RedisAsyncCommands<String, String> async = connection.async();

          async.multi();
          async.set("key", "value");
          async.set("key2", "value2");
          System.out.println("Executed commands in pipeline");
          return async.exec().whenComplete((s, throwable) -> pool.release(connection));
        });
    transactionResult.join();

    // terminating
    pool.closeAsync();

    // after pool completion
    client.shutdownAsync();
  }
}

在此设置中,LettuceConnectionFactory 是您需要实现的自定义类,它遵循 Apache Commons Pool 的 PooledObjectFactory 接口,以管理池化 StatefulRedisConnection 对象的生命周期事件。

DNS 缓存和 Redis

当您连接到具有多个端点的 Redis 数据库(例如 Redis Enterprise Active-Active)时,建议禁用 JVM 的 DNS 缓存以跨多个端点平衡负载请求。

您可以在应用程序的代码中使用以下代码段执行此操作

java.security.Security.setProperty("networkaddress.cache.ttl","0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl", "0");

了解更多信息

对本页进行评分