上一期我们聊了Jedis的相关操作以及Lettuce的特点,即:对分布式缓存框架支持相对较多,并且同样使用Netty,方法调用也是异步的,线程安全。在一些分布式缓存框架上使用相对比较多,今天呢我会跟大家聊一下如何通过Lettuce将Redis应用到我们的JAVA项目中。关于集群和哨兵的话计划是后边专门开一期去讲因为内容比较多,所以今天就简单带过。
一.Lettuce的组成
在讲如何继承Lettuce到我们的项目中之前,我先讲讲Lettuce的大致框架结构,因为他跟我们传统的Redis使用方式区别有点大,所以先讲讲Lettuce的大致结构方便大家理解,如果不想深入了解的话可以直接跳到下面看如何集成到项目中。
首先呢,Lettuce使用的时候主要依赖四个组件:
1.RedisURI:连接信息。
2.RedisClient:Redis客户端
3.Connection:Redis连接
4.RedisCommands:Redis命令API接口
1.RedisURI:连接信息
想通过JAVA操作Redis第一步肯定要先连接到Redis,RedisURI就是连接到Reids的参数,比如地址,端口,用户名,密码,连接超时时间等
//创建URI方式一(使用字符串创建):
RedisURI redisUri = RedisURI.create("redis://localhost/");
//创建URI方式二(使用builder建造器创建):
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建方式三(使用有参构造函数直接实例化):
RedisURI redisUri = new RedisURI("localhost",6379,Duration.ofSeconds(600));
使用方式一根据不同的RedisURI创建对应的连接信息
//Redis 单机版
redis :// [[username :] password@] host [:port][/database]
[?[timeout=timeout[d|h|m|s|ms|us|ns]]
//Redis 独立 (SSL)
rediss :// [[username :] password@] host [: port][/database]
[?[timeout=timeout[d|h|m|s|ms|us|ns]]
//Redis Standalone(Unix 域套接字)
redis-socket :// [[username :] password@]path
[?[timeout=timeout[d|h|m|s|ms|us|ns]] [&database=database]]
//Redis 哨兵
redis-sentinel :// [[username :] password@] host1[:port1] [, host2[:port2]] [, hostN[:portN]] [/database]
[?[timeout=timeout[d|h|m|s|ms|us|ns]] [&sentinelMasterId=sentinelMasterId]
2.RedisClient:Redis客户端
很好理解,拿着前面的连接信息然后实例化Redis客户端
//创建普通客户端
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
RedisClient redisClient = RedisClient.create(redisUri);
//关闭客户端
redisClient.shutdown();
//Redis创建集群客户端一:
RedisURI redisUri6379 = RedisURI.builder().withHost("localhost").withPort(6379).build();
RedisClusterClient redisClusterClient79 = RedisClusterClient.create(redisUri6379);
//Redis创建集群客户端二:
RedisURI redisUri6380 = RedisURI.builder().withHost("localhost").withPort(6380).build();
RedisClusterClient redisClusterClient80 = RedisClusterClient.create(redisUri6380);
//关闭客户端
redisClusterClient79.shutdown();
redisClusterClient80.shutdown();
3.Connection:Redis连接(重要)
有了客户端接下来就是连接到服务器,要根据连接类型选择不同的方法创建不同类型的连接,连接池的话可以参考上一期的Jedis连接池自行延伸,计划在后面几期在讲集群时再进行详细介绍。
这里的返回值都是
StatefulConnection
或者StatefulRedisConnection
的子类,连接的类型主要由连接的具体方式决定,简单介绍一下几个主要方法
(1)创建普通类型的连接
//创建URI
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//连接
StatefulRedisConnection<String, String> connect = redisClient.connect();
//-------代码---------
//...
//-------End---------
//关闭连接
connect.close();
//关闭客户端
redisClient.shutdown();
(2)创建哨兵类型的连接
//创建URI
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//连接
StatefulRedisSentinelConnection<String, String> stringStringStatefulRedisSentinelConnection = redisClient.connectSentinel();
//-------代码---------
//...
//-------End---------
//关闭连接
connect.close();
//关闭客户端
redisClient.shutdown();
(3)创建发布订阅类型的连接
//创建URI
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//连接
StatefulRedisPubSubConnection<String, String> stringStringStatefulRedisPubSubConnection = redisClient.connectPubSub();
//-------代码---------
//...
//-------End---------
//关闭连接
connect.close();
//关闭客户端
redisClient.shutdown();
4.RedisCommands:Redis指令API接口
基本上覆盖了Redis当前版本的所有命令、提供了同步(sync)、异步(async)、响应式(reative)的调用方式,对于我们来说,前面三步都是为了建立连接,到这里才是我们对Redis的操作
同步 API 的一般方法与异步 API 没有什么不同。在这两种情况下,都使用相同的工具来调用命令并将命令传输到 Redis 服务器。唯一的区别是使用同步 API 的调用者的阻塞行为。阻塞发生在命令级别,仅影响命令完成部分,就是说使用同步 API 的多个客户端可以在同一连接上同时调用命令,而不会相互阻塞。
异步方法可以更好的利用系统资源,而不是浪费线程等待网络或磁盘 I/O。可以充分利用线程来执行其他工作。Lettuce 通过在 netty 之上构建客户端来实现异步,netty 是一个多线程、事件驱动的 I/O 框架。所有通信都是异步处理的。可以进一步提升我们处理命令的效率。
关于响应式调用方式因为没有做过了解也没有实际使用过,没有做过深入研究,Spring Data Redis对其也有一定的支持,等空了研究一下再回来补上吧。
(1)同步
//创建URI
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//连接
StatefulRedisConnection<String, String> connect = redisClient.connect();
//操作连接(同步)
connect.sync().set("user", "victory");
//拿取结果
String user = connect.sync().get("user");
System.out.println(user);
//关闭连接
connect.close();
//关闭客户端
redisClient.shutdown();
(2)异步
//创建URI
RedisURI redisUri = RedisURI.builder().withHost("localhost").withPort(6379).build();
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//连接
StatefulRedisConnection<String, String> connect = redisClient.connect();
//操作连接(异步)
connect.async().set("user", "victory2");
//拿取结果最多等待1秒
String user = connect.async().get("user").get(1, TimeUnit.SECONDS);
System.out.println(user);
//关闭连接
connect.close();
//关闭客户端
redisClient.shutdown();
二.JAVA代码集成:
1.导包
这里如果是Maven项目可以直接去Maven仓库下,也可以去Lettuce官网下载源码然后打成Jar包直接引入
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.1.8.RELEASE</version>
</dependency>
2.代码示例
我用了junit的测试,需要的话自行导包
package cn.victory.patternOne;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import org.junit.Test;
/**
* @Description LettuceDemo
* @Author victory
* @Date 2022/6/7
**/
public class Lettuce {
@Test
public void testLettuce(){
//创建URI客户端参数
RedisURI redisUri = RedisURI.create("redis://localhost/");
//创建客户端
RedisClient redisClient = RedisClient.create(redisUri);
//创建连接
StatefulRedisConnection<String, String> connection = redisClient.connect();
//创建同步命令
RedisCommands<String, String> commands = connection.sync();
//设置值
commands.set("user", "victory");
//获取值
String user = commands.get("user");
System.out.println(user);
//关闭连接
connection.close();
//关闭客户端
redisClient.shutdown();
}
}
三:总结
Lettuce 相较于Jedis,使用上更加方便快捷,抽象度高。并且通过线程安全的连接降低了系统中的连接数量,提升了系统的稳定性。
对于中高级玩家,Lettuce 也提供了很多配置、接口,方便对性能进行优化和实现深度业务定制的场景。
今天就到这里,早就写好了一直忘记发出来了,下面几期会分别介绍Redison,还有遥遥无期的集群和相关的高频知识点。还望各位看官点个赞再走吧,给您劈个叉~
参考文献: