Redis7——基础篇(八)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。
基础篇:
- Redis(一)
- Redis(二)
- Redis(三)
- Redis(四)
- Redis(五)
- Redis(六)
- Redis(七)
接上期内容:上期完成了Redis集群的学习。下面开始学习Java集成Redis,话不多说,直接发车。
一、Java连接Redis的四种方式
(一)、底层客户端库
1、Jedis
1.1、定义
Jedis是Redis官方推荐的Java客户端,它提供了一套简洁易用的 API,用于与Redis 进行交互。Jedis支持同步、异步和管道操作,能够满足不同场景下的需求。
1.2、优劣势
优势:
- 使用简单,学习成本低,对初学者友好。
- 同步阻塞 I/O,在单线程环境下使用方便。
- 与 Redis的命令对应性强,容易上手。
劣势:
- 在高并发场景下,由于同步阻塞 I/O 的特性,性能会受到一定影响。
- 多线程环境下,需要手动管理连接池,增加了开发复杂度。
2、Lettuce
2.1、定义
Lettuce是一个基于Netty的可伸缩线程安全的Redis客户端,它支持同步、异步和响应式编程模型。Lettuce的设计目标是提供高性能和可扩展性,适用于各种复杂的应用场景。
2.2、优劣势
优势:
- 基于Netty实现,支持异步 I/O,在高并发场景下性能表现出色。
- 线程安全,无需手动管理连接池。
- 支持多种编程模型,灵活性高。
劣势:
- 相比Jedis,学习成本较高。
-
API相对复杂,对于简单场景可能显得过于繁琐。
(二)、上层框架封装
1、RedisTemplate
1.1、定义
RedisTemplate是Spring Data Redis 提供的一个高级封装,它简化了Java与Redis的交互操作。RedisTemplate提供了丰富的方法,支持各种数据结构的操作,并且可以方便地进行事务管理和序列化配置。
1.2、优劣势
优势:
- 与Spring 架无缝集成,使用方便。
- 对各种数据结构的操作进行了封装,代码简洁。
- 支持事务管理和序列化配置,提高了应用的灵活性和可维护性。
劣势:
- 依赖Spring框架,如果项目中没有使用 Spring,引入RedisTemplate会增加项目的复杂度。
- 相比底层客户端库,性能上可能会有一定损耗。
2、Redisson
2.1、定义
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,如分布式锁、分布式集合、分布式对象等,极大地简化了分布式系统的开发。
2.2、优劣势
优势:
- 提供了丰富的分布式服务,开箱即用,像分布式锁、分布式集合等,非常适合构建分布式系统。
- 对Redis功能进行了高度抽象和扩展,使用起来更加便捷。
- 支持多种序列化方式,兼容性好。
劣势:
- 相比直接使用 Redis 客户端,增加了一定的学习成本。
- 由于其功能丰富,依赖的包可能较多,在一些对依赖大小敏感的场景下不太适用。
二、实操
(一)、集成Jedis
1、新建项目
新建步骤略。最终效果图:
2、导入依赖
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
3、编写方法
3.1、连接redis单机
public class JedisDemoTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.112.129", 6379);
jedis.auth("root");
jedis.set("k1", "你好jedis");
System.out.println(jedis.get("k1"));
//key
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println(key);
}
System.out.println("jedis.exists====>" + jedis.exists("k2"));
System.out.println(jedis.ttl("k1"));
//String
System.out.println(jedis.get("k1"));
jedis.set("k4", "k4_redis");
System.out.println("----------------------------------------");
jedis.mset("str1", "v1", "str2", "v2", "str3", "v3");
System.out.println(jedis.mget("str1", "str2", "str3"));
//list
System.out.println("----------------------------------------");
jedis.lpush("myList", "v1", "v2", "v3", "v4", "v5");
List<String> list = jedis.lrange("myList", 0, -1);
for (String element : list) {
System.out.println(element);
}
//set
jedis.sadd("orders", "jd001");
jedis.sadd("orders", "jd002");
jedis.sadd("orders", "jd003");
Set<String> set1 = jedis.smembers("orders");
for (String string : set1) {
System.out.println(string);
}
jedis.srem("orders", "jd002");
System.out.println(jedis.smembers("orders").size());
//hash
jedis.hset("hash1", "userName", "lisi");
System.out.println(jedis.hget("hash1", "userName"));
Map<String, String> map = new HashMap<>();
map.put("telephone", "138xxxxxxxx");
map.put("address", "fatigue");
map.put("email", "sxxxx@qq.com");//
jedis.hmset("hash2", map);
List<String> result = jedis.hmget("hash2", "telphone", "email");
for (String element : result) {
System.out.println(element);
}
//zSet
jedis.zadd("zSet01", 60d, "v1");
jedis.zadd("zSet01", 70d, "v2");
jedis.zadd("zSet01", 80d, "v3");
jedis.zadd("zSet01", 90d, "v4");
List<String> zSet01 = jedis.zrange("zSet01", 0, -1);
zSet01.forEach(System.out::println);
// 关闭连接
jedis.close();
}
}
3.2、连接redis集群
public class JedisColonyDemoTest {
public static void main(String[] args) {
// 添加主节点
HashSet<HostAndPort> jedisClusterNodes = new HashSet<>();
jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6379));
jedisClusterNodes.add(new HostAndPort("192.168.112.130", 6381));
jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6380));
// 连接redis集群
JedisCluster cluster = new JedisCluster(jedisClusterNodes,"default","root");
// 清除单机Redis设置的key
// 如果用Jedis连接Redis集群模式下,
// flushAll这类全局操作不能直接使用,在集群模式下对于一些全局操作命令(如 KEYS)的处理不够完善,
// 没有内置的逻辑来处理 KEYS 命令在集群环境下的复杂性。
for (HostAndPort node : jedisClusterNodes) {
try (Jedis jedis = new Jedis(node.getHost(), node.getPort())) {
jedis.auth("root");
// 对每个节点执行 flushDB 命令
jedis.flushDB();
System.out.println("Flushed database on node: " + node);
}
}
cluster.set("k1", "你好redis集群");
System.out.println(cluster.get("k1"));
System.out.println("cluster.exists====>" + cluster.exists("k2"));
System.out.println(cluster.ttl("k1"));
//String
System.out.println(cluster.get("k1"));
cluster.set("k4", "k4_redis");
System.out.println("----------------------------------------");
cluster.mset("str1{x}", "v1", "str2{x}", "v2", "str3{x}", "v3");
System.out.println(cluster.mget("str1{x}", "str2{x}", "str3{x}"));
//list
System.out.println("----------------------------------------");
cluster.lpush("myList", "v1", "v2", "v3", "v4", "v5");
List<String> list = cluster.lrange("myList", 0, -1);
for (String element : list) {
System.out.println(element);
}
//set
cluster.sadd("orders", "jd001");
cluster.sadd("orders", "jd002");
cluster.sadd("orders", "jd003");
Set<String> set1 = cluster.smembers("orders");
for (String string : set1) {
System.out.println(string);
}
cluster.srem("orders", "jd002");
System.out.println(cluster.smembers("orders").size());
//hash
cluster.hset("hash1", "userName", "lisi");
System.out.println(cluster.hget("hash1", "userName"));
Map<String, String> map = new HashMap<>();
map.put("telephone", "138xxxxxxxx");
map.put("address", "fatigue");
map.put("email", "sxxxx@qq.com");//
cluster.hmset("hash2", map);
List<String> result = cluster.hmget("hash2", "telphone", "email");
for (String element : result) {
System.out.println(element);
}
//zSet
cluster.zadd("zSet01", 60d, "v1");
cluster.zadd("zSet01", 70d, "v2");
cluster.zadd("zSet01", 80d, "v3");
cluster.zadd("zSet01", 90d, "v4");
List<String> zSet01 = cluster.zrange("zSet01", 0, -1);
zSet01.forEach(System.out::println);
cluster.close();
}
}
4、测试用例
4.1、单机测试结果
直接main方法启动,
redis客户端:
4.2、redis集群测试结果
控制台输入:
redis客户端:
(二)、集成Lettuce
1、导入依赖
<!--lettuce-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.5.4.RELEASE</version>
</dependency>
*注意:如果你的Springboot版本为3.4.3,那么导入这个依赖后,可能需要清除IDEA缓存,不然一直无法new RedisURI类。刷新过maven也没用,只有清除缓存重启后才成功,就很奇怪( ╯□╰ )。
2、编写方法
2.1、连接Redis单机
public class LettuceDemoTest {
public static void main(String[] args) {
// 构建 RedisURI 对象
RedisURI uri = RedisURI.builder(RedisURI.create("redis://192.168.112.129"))
.withPort(6379)
.withAuthentication("default", "root")
.withDatabase(0)
.build();
// 创建连接客户端
RedisClient client = RedisClient.create(uri);
StatefulRedisConnection<String, String> conn = client.connect();
// 操作命令api
RedisCommands<String, String> commands = conn.sync();
// 清空Jedis设置的key
commands.flushdb();
//keys
List<String> list = commands.keys("*");
for (String s : list) {
System.out.println(s);
}
//String
commands.set("k1", "hello Lettuce");
String s1 = commands.get("k1");
System.out.println("String s ===" + s1);
//list
commands.lpush("myList2", "v1", "v2", "v3");
List<String> list2 = commands.lrange("myList2", 0, -1);
for (String s : list2) {
System.out.println("list ssss===" + s);
}
//set
commands.sadd("mySet2", "v1", "v2", "v3");
Set<String> set = commands.smembers("mySet2");
for (String s : set) {
System.out.println("set ssss===" + s);
}
//hash
Map<String, String> map = new HashMap<>();
map.put("k1", "138xxxxxxxx");
map.put("k2", "fatigue");
map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件
commands.hmset("myHash2", map);
Map<String, String> retMap = commands.hgetall("myHash2");
for (String k : retMap.keySet()) {
System.out.println("hash k=" + k + " , v==" + retMap.get(k));
}
//zSet
commands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");
List<String> list3 = commands.zrange("myzSet2", 0, 10);
for (String s : list3) {
System.out.println("zSet ssss===" + s);
}
//sort
SortArgs sortArgs = new SortArgs();
sortArgs.alpha();
sortArgs.desc();
List<String> list4 = commands.sort("myList2", sortArgs);
for (String s : list4) {
System.out.println("sort ssss===" + s);
}
//关闭
conn.close();
client.shutdown();
}
}
2.2、连接Redis集群
public class LettuceColonyDemoTest {
public static void main(String[] args) {
HashSet<RedisURI> uris = new HashSet<>();
uris.add(RedisURI.builder().withHost("192.168.112.129")
.withPort(6379).withAuthentication("default", "root").build());
uris.add(RedisURI.builder().withHost("192.168.112.130")
.withPort(6381).withAuthentication("default", "root").build());
uris.add(RedisURI.builder().withHost("192.168.112.129")
.withPort(6380).withAuthentication("default", "root").build());
RedisClusterClient client = RedisClusterClient.create(uris);
StatefulRedisClusterConnection<String, String> con = client.connect();
RedisAdvancedClusterCommands<String, String> clusterCommands = con.sync();
// 清除单机Redis设置的key
// Lettuce连接Redis集群模式下,能使用flushAll命令
// 因为Lettuce内部实现了智能的路由机制,能够自动将 KEYS 命令分发到集群中的各个节点,并将结果聚合返回
clusterCommands.flushallAsync();
//keys
List<String> list = clusterCommands.keys("*");
for (String s : list) {
System.out.println(s);
}
//String
clusterCommands.set("k1", "hello Lettuce");
String s1 = clusterCommands.get("k1");
System.out.println("redis集群===" + s1);
//list
clusterCommands.lpush("myList2", "v1", "v2", "v3");
List<String> list2 = clusterCommands.lrange("myList2", 0, -1);
for (String s : list2) {
System.out.println("list ssss===" + s);
}
//set
clusterCommands.sadd("mySet2", "v1", "v2", "v3");
Set<String> set = clusterCommands.smembers("mySet2");
for (String s : set) {
System.out.println("set ssss===" + s);
}
//hash
Map<String, String> map = new HashMap<>();
map.put("k1", "138xxxxxxxx");
map.put("k2", "fatigue");
map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件
clusterCommands.hmset("myHash2", map);
Map<String, String> retMap = clusterCommands.hgetall("myHash2");
for (String k : retMap.keySet()) {
System.out.println("hash k=" + k + " , v==" + retMap.get(k));
}
//zSet
clusterCommands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");
List<String> list3 = clusterCommands.zrange("myzSet2", 0, 10);
for (String s : list3) {
System.out.println("zSet ssss===" + s);
}
//sort
SortArgs sortArgs = new SortArgs();
sortArgs.alpha();
sortArgs.desc();
List<String> list4 = clusterCommands.sort("myList2", sortArgs);
for (String s : list4) {
System.out.println("sort ssss===" + s);
}
//关闭
con.close();
client.shutdown();
client.close();
}
}
3、测试用例
3.1、单机测试结果
控制台输出:
redis客户端:
3.2、redis集群测试结果
控制台输出:
redis客户端:
(三)、集成RedisTemplate
1、新建配置文件
新建application.properties文件:
server.port=8080
spring.application.name=RedisDemo
# ========================logging=====================
logging.level.root=info
logging.level.xxx.xx.xxx=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n
logging.file.name=D:/myLogs/RedisDemo.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n
# ========================redis单机=====================
spring.data.redis.database=0
#修改为自己的真实IP
spring.data.redis.host=xxx.xxx.xxx.xxx
spring.data.redis.port=6379
spring.data.redis.password=xxxx
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1ms
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0
2、导入依赖
<!--SpringBoot通用依赖模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBoot与Redis整合依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--日志-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.24.3</version>
</dependency>
<!-- swagger3生成接口文档依赖-->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
3、编写业务类
3.1、新建controller
@RestController
@Tag(name = "订单管理", description = "订单的创建和查询操作")
public class OrderController {
@Resource
private OrderService orderService;
/**
* redis单机
*/
@RequestMapping(value = "/order/add", method = RequestMethod.POST)
public void addOrder() {
orderService.addOrder();
}
@RequestMapping(value = "/order/{id}", method = RequestMethod.GET)
public String findUserById(@PathVariable Integer id) {
return orderService.getOrderById(id);
}
/**
* redis集群
*/
@RequestMapping(value = "/cluster/order/add", method = RequestMethod.POST)
public void clusterAddOrder() {
orderService.clusterAddOrder();
}
@RequestMapping(value = "cluster/order/{id}", method = RequestMethod.GET)
public String clusterFindUserById(@PathVariable Integer id) {
return orderService.clusterFindUserById(id);
}
}
3.2、新建service
*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习
@Service
@Slf4j
public class OrderService {
public static final String ORDER_KEY = "order:";
@Resource
private RedisTemplate<String, String> redisTemplate;
public void addOrder() {
int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
String orderNo = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);
log.info("redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);
}
public String getOrderById(Integer id) {
System.out.println(redisTemplate.opsForList().range("myList", 0, -1));
HashMap<String, String> map = new HashMap<>();
map.put("k1", "k2");
map.put("k3", "k4");
map.put("k5", "k6");
redisTemplate.opsForValue().multiSet(map);
return redisTemplate.opsForValue().get(ORDER_KEY + id);
}
public void clusterAddOrder() {
int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
String orderNo = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);
log.info("redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);
}
public String clusterFindUserById(Integer id) {
return redisTemplate.opsForValue().get(ORDER_KEY + id);
}
}
3.3、新建config
这个配置主要是生成接口文档。
@Configuration
public class OpenAPIConfig {
@Bean
public OpenAPI customOpenAPI() {
String currentDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now());
return new OpenAPI().info(new Info()
.title("springBoot利用swagger3构建api接口文档 " + "\t" + currentDate)
.description("springboot+redis整合")
.version("1.0")
.termsOfService("https://www.baidu.com/"));
}
}
3.4、连接redis单机
3.5、连接redis集群
4、测试接口
启动项目,访问http://localhost:8080/swagger-ui/index.html
4.1、单机测试结果
控制台输出:
redis客户端:
Q:数据是存进去了,但是为啥是乱码的?在连接redis客户端的时候加上了-c的参数还是乱码?为啥通过接口获取的数据是正常的,但是通过redis客户端去查看的又是乱码?
A:是因为序列化方式不一致造成。键(key)和值(value)都是通过spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer。解决办法就是统一序列化方式。
新建RedisConfig类:
@Configuration
public class RedisConfig {
/**
*设置存储key的序列化方式
* @param redisConnectionFactory 创建与Redis连接的工厂类
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置String
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
// 设置hash、set、zSet、list.....
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
重启项目,重新测试:
问题解决。
4.2、redis集群测试结果
修改application.properties文件,注释redis单机配置:
重启项目,进行测试:
redis客户端:
初步看来,连接redis集群没毛病。
Q:假设集群中,有主机服务宕机了,从机上位后,程序是否还能正常从redis集群获取与写入数据呢?
A:读能正常,但是写不正常
手动关闭6379,模拟测试一下。
是需要手动开启刷新节点拓扑网落的,
#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.data.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新 毫秒
spring.data.redis.lettuce.cluster.refresh.period=2000
不然,当某个Master主机宕机后,虽然从机上位了,但还是不可用的(针对于这个key刚好落在宕机的Master上)。
(四)、集成Redisson
1、导入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.45.0</version>
</dependency>
2、编写业务类
2.1、新建controller
@RestController
@Tag(name = "Redisson订单管理", description = "订单的创建和查询操作")
public class RedissonOrderController {
@Resource
private RedissonOrderService redissonOrderService;
/**
* redisson连接redis单机
*/
@RequestMapping(value = "/redisson/order/add", method = RequestMethod.POST)
public void redissonAddOrder() {
redissonOrderService.redissonAddOrder();
}
@RequestMapping(value = "/redisson/order/{id}", method = RequestMethod.GET)
public String redissonFindUserById(@PathVariable Integer id) {
return redissonOrderService.redissonFindUserById(id);
}
/**
* redisson连接redis集群
*/
@RequestMapping(value = "/redisson/cluster/order/add", method = RequestMethod.POST)
public void redissonClusterAddOrder() {
redissonOrderService.redissonClusterAddOrder();
}
@RequestMapping(value = "/redisson/cluster/order/{id}", method = RequestMethod.GET)
public String redissonClusterFindUserById(@PathVariable Integer id) {
return redissonOrderService.redissonClusterFindUserById(id);
}
}
2.2、新建service
*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习。
@Service
@Slf4j
public class RedissonOrderService {
public static final String ORDER_KEY = "order:";
private final RedissonClient redissonSingleClient;
private final RedissonClient redissonColonyClient;
@Autowired
public RedissonOrderService(@Qualifier("redissonColonyClient") RedissonClient redissonColonyClient,
@Qualifier("redissonSingleClient") RedissonClient redissonSingleClient) {
this.redissonColonyClient = redissonColonyClient;
this.redissonSingleClient = redissonSingleClient;
}
public void redissonAddOrder() {
int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
String orderNo = UUID.randomUUID().toString();
redissonSingleClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);
log.info("redisson连接redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);
}
public String redissonFindUserById(Integer id) {
RBucket<Object> bucket = redissonSingleClient.getBucket(ORDER_KEY + id);
return (String) bucket.get();
}
public void redissonClusterAddOrder() {
int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
String orderNo = UUID.randomUUID().toString();
redissonColonyClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);
log.info("redisson连接redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);
}
public String redissonClusterFindUserById(Integer id) {
RBucket<Object> bucket = redissonColonyClient.getBucket(ORDER_KEY + id);
return (String) bucket.get();
}
}
2.3、新建config
@Configuration
public class RedissonConfig {
/**
* redisson连接redis单机
*/
@Bean(name = "redissonSingleClient")
@Primary
public RedissonClient redissonSingleClient() {
Config config = new Config();
// 单机模式
config.useSingleServer().setAddress("redis://192.168.112.131:6381").setPassword("root");
// 设置 JSON 序列化编解码器
config.setCodec(new JsonJacksonCodec(new ObjectMapper()));
return Redisson.create(config);
}
/**
* redisson连接redis集群
*/
@Bean(name = "redissonColonyClient")
public RedissonClient redissonColonyClient() {
Config config = new Config();
// 设置JSON序列化编解码器
config.setCodec(new JsonJacksonCodec(new ObjectMapper()));
// 集群模式
config.useClusterServers().addNodeAddress("redis://192.168.112.129:6379",
"redis://192.168.112.129:6380",
"redis://192.168.112.130:6381",
"redis://192.168.112.130:6382",
"redis://192.168.112.131:6383",
"redis://192.168.112.131:6384")
.setScanInterval(2000)// 集群状态扫描间隔时间,单位是毫秒
.setPassword("root");
return Redisson.create(config);
}
}
2.4、连接redis单机
2.5、连接redis集群
3、测试接口
3.1、单机测试结果
控制台输出:
redis客户端:
3.2、redis集群测试结果
控制台输出:
redis客户端:
三、总结
在Java开发中,与 Redis 进行高效整合是提升系统性能和可扩展性的关键环节。本文为你详细介绍四种主流的Java整合Redis的方式,涵盖底层客户端库Jedis和Lettuce,以及上层框架封装RedisTemplate和Redisson。
Jedis以其简单易懂的使用方式脱颖而出,对于刚刚接触 Redis 集成的初学者而言,它就像一位耐心的导师,引导着开发者逐步熟悉 Redis的操作。同时,由于其在单线程环境下表现稳定,成为单线程应用场景的理想选择。
Lettuce则凭借卓越的性能在高并发领域独树一帜。它基于 Netty 实现,具备出色的异步处理能力和线程安全性,能够在高并发的浪潮中稳健前行,为高并发场景提供强大的支持。
RedisTemplate与Spring框架深度融合,仿佛是为Spring项目量身定制的利器。在 Spring 项目中,使用RedisTemplate可以轻松地与其他Spring组件协同工作,极大地提高了开发效率,让开发者能够更加专注于业务逻辑的实现。
Redisson作为一个独立的框架,不依赖于任何特定的框架,它专注于分布式系统的开发,提供了丰富的分布式数据结构和服务,如分布式锁、分布式集合等,为分布式系统的搭建提供了全方位的解决方案。
在实际的项目开发中,我们应根据项目的具体需求和应用场景,审慎地选择合适的整合方式。希望本文能够帮助你更好地掌握 Java与Redis的集成技术,为项目注入强大的性能和可扩展性动力。
ps:努力到底,让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。