Redis Java Lettuce驱动框架原理解析

 更新时间:2020年12月04日 15:11:04   作者:codedot  
这篇文章主要介绍了Redis Java Lettuce驱动框架原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Lettuce是一个高性能基于Java编写的Redis驱动框架,底层集成了Project Reactor提供天然的反应式编程,通信框架集成了Netty使用了非阻塞IO,5.x版本之后融合了JDK1.8的异步编程特性,在保证高性能的同时提供了十分丰富易用的API,5.1版本的新特性如下:

  • 支持Redis的新增命令ZPOPMIN, ZPOPMAX, BZPOPMIN, BZPOPMAX。
  • 支持通过Brave模块跟踪Redis命令执行。
  • 支持Redis Streams。
  • 支持异步的主从连接。
  • 支持异步连接池。
  • 新增命令最多执行一次模式(禁止自动重连)。
  • 全局命令超时设置(对异步和反应式命令也有效)。
  • ......等等

注意一点:Redis的版本至少需要2.6,当然越高越好,API的兼容性比较强大。

引入依赖项:

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

一、连接Redis

单机、哨兵、集群模式下连接Redis需要一个统一的标准去表示连接的细节信息,在Lettuce中这个统一的标准是RedisURI。可以通过三种方式构造一个RedisURI实例:

定制的字符串URI语法:

RedisURI uri = RedisURI.create("redis://localhost/");

使用建造器(RedisURI.Builder):

RedisURI uri = RedisURI.builder().withHost("localhost").withPort(6379).build();

直接通过构造函数实例化:

RedisURI uri = new RedisURI("localhost", 6379, 60, TimeUnit.SECONDS);

二、基本使用

Lettuce使用的时候依赖于四个主要组件:

  • RedisURI:连接信息。
  • RedisClient:Redis客户端,特殊地,集群连接有一个定制的RedisClusterClient。
  • Connection:Redis连接,主要是StatefulConnection或者StatefulRedisConnection的子类,连接的类型主要由连接的具体方式(单机、哨兵、集群、订阅发布等等)选定,比较重要。
  • RedisCommands:Redis命令API接口,基本上覆盖了Redis发行版本的所有命令,提供了同步(sync)、异步(async)、反应式(reative)的调用方式,对于使用者而言,会经常跟RedisCommands系列接口打交道。

一个基本使用例子如下:

RedisURI redisUri = RedisURI.builder()          // <1> 创建单机连接的连接信息
    .withHost("localhost")
    .withPort(6379)
    .withTimeout(Duration.of(10, ChronoUnit.SECONDS))
    .build();
RedisClient redisClient = RedisClient.create(redisUri);  // <2> 创建客户端
StatefulRedisConnection<String, String> connection = redisClient.connect();   // <3> 创建线程安全的连接
RedisCommands<String, String> redisCommands = connection.sync();        // <4> 创建同步命令
SetArgs setArgs = SetArgs.Builder.nx().ex(5);
String result = redisCommands.set("name", "throwable", setArgs);
result = redisCommands.get("name");
System.out.println(result);
// ... 其他操作
connection.close();  // <5> 关闭连接
redisClient.shutdown(); // <6> 关闭客户端

关闭连接一般在应用程序停止之前操作,一个应用程序中的一个Redis驱动实例不需要太多的连接(一般情况下只需要一个连接实例就可以,如果有多个连接的需要可以考虑使用连接池,其实Redis目前处理命令的模块是单线程,在客户端多个连接多线程调用理论上没有效果)。

关闭客户端一般应用程序停止之前操作,如果条件允许的话,基于后开先闭原则,客户端关闭应该在连接关闭之后操作。

三、Lettuce API

  • 同步(sync):RedisCommands。
  • 异步(async):RedisAsyncCommands。
  • 反应式(reactive):RedisReactiveCommands。
RedisURI redisUri = RedisURI.builder()
    .withHost("localhost")
    .withPort(6379)
    .withTimeout(Duration.of(10, ChronoUnit.SECONDS))
    .build();
RedisClient client = RedisClient.create(redisUri);
StatefulRedisConnection<String, String> connection = client.connect();

Redis命令API的具体实现可以直接从StatefulRedisConnection实例获取,见其接口定义:

public interface StatefulRedisConnection<K, V> extends StatefulConnection<K, V> {
  boolean isMulti();
  RedisCommands<K, V> sync();
  RedisAsyncCommands<K, V> async();
  RedisReactiveCommands<K, V> reactive();
} 

值得注意的是,在不指定编码解码器RedisCodec的前提下,RedisClient创建的StatefulRedisConnection实例一般是泛型实例StatefulRedisConnection<String,String>,也就是所有命令API的KEY和VALUE都是String类型,这种使用方式能满足大部分的使用场景。当然,必要的时候可以定制编码解码器RedisCodec<K,V>。

同步API

先构建RedisCommands实例

RedisCommands<String, String> redisCommands= connection.sync();
String pong = redisCommands.ping();
// 返回PONG
System.out.println("pong:" + pong);

SetArgs setArgs = SetArgs.Builder.nx().ex(5);
redisCommands.set("name", "throwable", setArgs);
String value = redisCommands.get("name");
System.out.println("name:" + value);

同步API在所有命令调用之后会立即返回结果。如果熟悉Jedis的话,RedisCommands的用法其实和它相差不大。

异步API

先构建RedisAsyncCommands实例:

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

基本使用:

RedisAsyncCommands<String, String> redisCommands = connection.async();
RedisFuture<String> redisFuture = redisCommands.ping();
// 返回PONG
System.out.println("pong:" + redisFuture.get());

SetArgs setArgs = SetArgs.Builder.nx().ex(5);
RedisFuture<String> future = redisCommands.set("name", "throwable", setArgs);
System.out.println("name:" + future.get());

RedisAsyncCommands所有方法执行返回结果都是RedisFuture实例,而RedisFuture接口的定义如下:

public interface RedisFuture<V> extends CompletionStage<V>, Future<V> {
  String getError();
  boolean await(long timeout, TimeUnit unit) throws InterruptedException;
}  

也就是,RedisFuture可以无缝使用Future或者JDK1.8中引入的CompletableFuture提供的方法。

反应式API

Lettuce引入的反应式编程框架是Project Reactor,如果没有反应式编程经验可以先自行了解一下Project Reactor。

构建RedisReactiveCommands实例:

RedisReactiveCommands<String, String> redisCommands = connection.reactive();

根据Project Reactor,RedisReactiveCommands的方法如果返回的结果只包含0或1个元素,那么返回值类型是Mono,如果返回的结果包含0到N(N大于0)个元素,那么返回值是Flux。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot集成kaptcha验证码

    SpringBoot集成kaptcha验证码

    这篇文章主要为大家详细介绍了SpringBoot集成kaptcha验证码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • 图解Java经典算法折半查找的原理与实现

    图解Java经典算法折半查找的原理与实现

    折半查找法也叫做⼆分查找,顾名思义就是把数据分成两半,再判断所查找的key在哪⼀半中,再重复上述步骤知道找到⽬标key,下面这篇文章主要介绍了图解Java经典算法折半查找的原理与实现
    2022-09-09
  • 以银行取钱为例模拟Java多线程同步问题完整代码

    以银行取钱为例模拟Java多线程同步问题完整代码

    这篇文章主要介绍了以银行取钱为例模拟Java多线程同步问题完整代码,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • SpringBoot设置默认主页的方法步骤

    SpringBoot设置默认主页的方法步骤

    这篇文章主要介绍了SpringBoot设置默认主页的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • springcloud本地调试feign调用出现的诡异404问题及解决

    springcloud本地调试feign调用出现的诡异404问题及解决

    这篇文章主要介绍了springcloud本地调试feign调用出现的诡异404问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 解读Spring定义Bean的两种方式:<bean>和@Bean

    解读Spring定义Bean的两种方式:<bean>和@Bean

    这篇文章主要介绍了Spring定义Bean的两种方式:<bean>和@Bean,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 基于java HashMap插入重复Key值问题

    基于java HashMap插入重复Key值问题

    这篇文章主要介绍了基于java HashMap插入重复Key值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java实现抠图片文字或签名的完整代码

    Java实现抠图片文字或签名的完整代码

    这篇文章主要介绍了java抠图片文字或签名的运行原理,本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • java执行SQL语句实现查询的通用方法详解

    java执行SQL语句实现查询的通用方法详解

    这篇文章主要介绍了java执行SQL语句实现查询的通用方法详解,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • java构造器复用方式

    java构造器复用方式

    这篇文章主要介绍了java构造器复用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论