Redis 7 第九讲 微服务集成Redis 应用篇

Jedis

理论

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

理论

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,管道,编码器等等功能。

spring-data-redis

单机

理论

RedisTemplate 继承自 RedisAccessor , 实现 RedisOperations 和 BeanClassLoaderAware 两个接口。spring-data-redis针对Jedis提供如下功能:

  1. 提供了一个高度封装的"RedisTemplate"类,里面封装了对于Redis的五种数据结构的各种操作

  2. SpringBoot2.x后,RedisTemplate采用是lettuce(基于netty采用异步非阻塞式lO)进行通信,大并发下比jedis效率更高。

  3. RedisTemplate模板使用序列化器操作redis数据

引入包

java 复制代码
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>
        </dependency>

案列演示

配置文件

java 复制代码
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)架构篇】,集群搭建如下

配置文件

java 复制代码
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默认是不会刷新节点拓扑

加入配置参数,动态刷新

java 复制代码
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
java 复制代码
#支持集群拓扑动态感应码斯,户适应拓扑树新是查使用所有可用的更斯,默认false 关闭spring.redis.lettuce.cluster .refresh,adaptive=true
#定时刷新
spring.redis,lettuce.cluster.refresh.period-2000

【源码地址】

相关推荐
JH30738 分钟前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
qq_12498707533 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_3 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
2301_818732063 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
此生只爱蛋4 小时前
【Redis】主从复制
数据库·redis
汤姆yu7 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶7 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
biyezuopinvip8 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
惊讶的猫9 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
JavaGuide9 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot