Jedis是redis的java版本的客户端实现,使用Jedis提供的Java API对Redis进行操作,是Redis官方推崇的方式;并且,使用Jedis提供的对Redis的支持也最为灵活、全面;不足之处,就是编码复杂度较高。
- <!--Jedis-->
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>4.3.1</version>
- </dependency>
获取Redis连接对象
-
- // 获取Jedis对象
- private static Jedis getJedis() {
- Jedis jedis = new Jedis("自己的地址", 端口);
- jedis.auth("111111");
- return jedis;
- }
Redis 案列
- Jedis jedis = getJedis();
- //geo
- String geo_key = getKey();
- jedis.geoadd(geo_key, getGeo());
- logger.info(String.valueOf(jedis.geodist(geo_key, "成都", "上海", GeoUnit.KM)));
-
-
- private static String getKey() {
- return "TOC-" + RandomUtil.randomString(6);
- }
-
-
- private static Map<String, GeoCoordinate> getGeo() {
- Map<String, GeoCoordinate> geoCoordinateHashMap = new HashMap<>(5);
- geoCoordinateHashMap.put("成都", new GeoCoordinate(103.954887, 30.569293));
- geoCoordinateHashMap.put("北京", new GeoCoordinate(116.427185, 39.93682));
- geoCoordinateHashMap.put("上海", new GeoCoordinate(121.477665, 31.236176));
- geoCoordinateHashMap.put("西安", new GeoCoordinate(108.952789, 34.36515));
- geoCoordinateHashMap.put("重庆", new GeoCoordinate(106.454377, 29.581309));
- return geoCoordinateHashMap;
- }
关闭Jedis对象
jedis.close();
获取连接池对象
- JedisPool jedisPool = getJedisPool();
- Jedis jedis = jedisPool.getResource();
-
- // 获取Jedispoll对象
- private static JedisPool getJedisPool() {
- GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
- poolConfig.setMaxIdle(8);
- poolConfig.setMinIdle(2);
- poolConfig.setMaxWait(Duration.ofSeconds(30000));
- return new JedisPool(poolConfig, "自己的ip", 端口, 100000, "111111");
- }
代码案列
- //hash
- String hash_key = getKey();
- jedis.hset(hash_key, getMapStr());
- for (String hkey : jedis.hkeys(hash_key)) {
- logger.info(jedis.hget(hash_key, hkey));
- }
关闭Jedis和Pool
- try {
- if (!Objects.isNull(jedis)) {
- jedis.close();
- }
- } finally {
- jedis = null;
- }
- try {
- if (Objects.isNull(jedisPool)){
- jedisPool.close();
- }
- } finally {
- jedisPool = null;
- }
优点 | 缺点 | |
直连 | 1.简单方便new-close 2.适用于连接数比较少且使用时间较长,可构成长连接的场景(只使用一个Jedis,比如down数据、大量数据更新) | 1.存在每次新建和关闭TCP的开销(三次握手四次挥手) 2.每次都去new,系统资源可能无法在有效范围内进行控制,会存在连接容易发生泄漏 3.Jedis对象本身是线程不安全的 |
池连接 | 1.Jedis是预先生成的,不需要随用随创,随用完随关闭,降低了这些开销 2.连接池能够更好地保护和控制资源使用,有固定的参数去控制最大连接数或者空闲数目等 | 1.相对直连,使用起来麻烦,特别是资源管理上需要非常多的参数来保证,一旦出现规划不合理的情况就会出现问题(比如池满、连接空闲、连接超时等情况) |
Lettuce 是一个可伸缩线程安全的 Redis 客户端。多个线程可以共享同一个 RedisConnection。它利用优秀 netty NIO 框架来高效地管理多个连接。
- <dependency>
- <groupId>io.lettuce</groupId>
- <artifactId>lettuce-core</artifactId>
- <version>6.2.5.RELEASE</version>
- </dependency>
获取连接对象
-
- private static StatefulRedisConnection<String, String> getRedis() {
- // 链式编程 创建RedisUri
- RedisURI build = RedisURI.builder().withHost("120.77.64.190").withPort(6379).withPassword("111111".toCharArray()).build();
-
- //创建客户端
- StatefulRedisConnection<String, String> conn = RedisClient.create().connect(build);
- return conn;
- }
-
-
- StatefulRedisConnection<String, String> conn = getRedis();
获取操作命令对象
- //链接command
- RedisCommands<String, String> jedis = conn.sync();
案列
-
- //geo
- String geo_key = getKey();
- jedis.geoadd(geo_key, 103.954887, 30.569293,"成都");
- jedis.geoadd(geo_key, 121.477665, 31.236176,"上海");
- logger.info(String.valueOf(jedis.geodist(geo_key, "成都", "上海", GeoArgs.Unit.km)));
关闭对象
- private static void closeConn(StatefulRedisConnection<String, String> conn) {
- // 关闭
- try {
- if (!Objects.isNull(conn)){
-
- conn.close();
- }
- }catch (Exception e){
- System.out.println(e);
- }finally {
- conn = null;
- }
- }
Lettuce 相比Jedis 客户端,功能更加强大,不仅解决了线程安全的问题,还支持异步和响应式编程,支持集群,Sentinel,管道,编码器等等功能。
RedisTemplate 继承自 RedisAccessor , 实现 RedisOperations 和 BeanClassLoaderAware 两个接口。spring-data-redis针对Jedis提供如下功能:
1. 提供了一个高度封装的“RedisTemplate”类,里面封装了对于Redis的五种数据结构的各种操作
2. SpringBoot2.x后,RedisTemplate采用是lettuce(基于netty采用异步非阻塞式lO)进行通信,大并发下比jedis效率更高。
3. RedisTemplate模板使用序列化器操作redis数据
-
-
org.springframework.boot -
spring-boot-starter-data-redis -
3.1.2 -
-
-
org.apache.commons -
commons-pool2 -
2.11.1 -
配置文件
- server:
- port: 8080
- spring:
- application:
- name: mop
- redis:
- host: 自己的ip
- port: 6379
- database: 0
- password: 111111
- lettuce:
- pool:
- max-active: 8
- max-idle: 8
- min-idle: 0
- max-wait: 3s
未加序列化配置
加入序列化配置
默认走JDK序列化
加入自定义配置
插入数据后,客户端显示正常
后续案列可自行实践
集群配置可参考 【Redis 7 第八讲 集群模式(cluster)架构篇】,集群搭建如下
- server:
- port: 8080
- spring:
- application:
- name: mop
- redis:
- cluster:
- max-redirects: 3
- nodes:
- - 自己的IP:端口
- - 自己的IP:端口
- - 自己的IP:端口
- - 自己的IP:端口
- - 自己的IP:端口
- - 自己的IP:端口
- database: 0
- password: 111111
- lettuce:
- pool:
- max-active: 8
- max-idle: 8
- min-idle: 0
- max-wait: 3s
意外模拟6381宕机,从机上位验证代码是否正常
写入时出现无法连接
原因分析:
SpringBoot 客户端无法动态感知到集群最新变化。
SpringBoot 2.X版本, Redis默认的连接池采用 Lettuce当Redis 集群节点发生变化后,Letture默认是不会刷新节点拓扑
加入配置参数,动态刷新
- server:
- port: 8080
- spring:
- application:
- name: mop
- redis:
- cluster:
- max-redirects: 3
- nodes:
- - IP:PORT
- - IP:PORT
- - IP:PORT
- - IP:PORT
- - IP:PORT
- - IP:PORT
- database: 0
- password: 111111
- lettuce:
- cluster:
- refresh:
- adaptive: true
- period: 2000
- pool:
- max-active: 8
- max-idle: 8
- min-idle: 0
- max-wait: -1ms
- #支持集群拓扑动态感应码斯,户适应拓扑树新是查使用所有可用的更斯,默认false 关闭spring.redis.lettuce.cluster .refresh,adaptive=true
- #定时刷新
- spring.redis,lettuce.cluster.refresh.period-2000
- 🌹 以上分享 Redis 客户端的应用,请指教🤝。
-
- 🌹🌹 如你对技术也感兴趣,欢迎交流。
-
- 🌹🌹🌹 如有需要,请👍点赞💖收藏🐱🏍分享