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

【源码地址】

相关推荐
xxl大卡30 分钟前
Redis完整详细学习笔记
redis·笔记·学习
Trouvaille ~1 小时前
【Redis篇】Hash 哈希:字段级操作与对象存储的最佳实践
数据库·redis·后端·算法·缓存·哈希算法·键值对
辞忧九千七1 小时前
吃透Redis7核心数据结构:从基础用法到实战场景(Python版)
开发语言·数据结构·redis·python
鱼鳞_2 小时前
苍穹外卖-Day08(购物车)
java·spring boot
nickel3692 小时前
Qoder相关使用
java·开发语言·vue.js·spring boot
码不停蹄的玄黓2 小时前
SpringBoot 自动装配原理
java·spring boot·后端
rising start3 小时前
Redis基础入门
数据库·redis·缓存
幻灭行度3 小时前
Redis ACL 实现多账号权限隔离
数据库·redis·oracle
Gauss松鼠会4 小时前
GaussDB(DWS) SQL性能问题案例集
java·数据库·经验分享·spring boot·后端·sql·gaussdb
霸道流氓气质4 小时前
Spring Boot 分页查询接口设计与实现 —— 技术总结与完整示例
java·spring boot·后端