• 【Spring Boot 集成应用】Redis的集成用法


    一、 Redis介绍

    Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库,具有以下特点:

    1. Redis 与其他 key - value 缓存产品有以下特点:

    • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
    • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
    • Redis支持数据的备份,即master-slave模式的数据备份。

    2. Redis特性优势:

    • 性能极高 – Redis单机能读的速度是110000次/s, 写的速度是81000次/s 。
    • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
    • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
    • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    二、 Spring Boot Redis 集成说明

    Java 封装的常用Redis框架有Jedis、Redisson和Lettuce等,这些框架帮我们解决了Redis的连接管理、API操作问题, Spring Boot 在 Lettuce基础上做了进一步封装, 提供了spring-boot-starter-data-redis组件, 帮助我们更为简化方便的使用Redis功能。 之所以选择Lettuce, 相比其他Redis框架,Lettuce是基于Netty框架的事件驱动实现,方法调用为异步处理。Lettuce的API操作是线程安全的, 三个框架对比:

    • Jedis:是老牌的Redis的Java实现客户端,提供了比较全面的Redis命令的支持, 但是对分布式锁、集群等功能支持不够完善。

    • Redisson:实现了分布式和可扩展的Java数据结构,但对于Redis的命令支持不够完善。

    • Lettuce:在线程安全同步,异步和响应使用上有较好的支持, 同时支持集群,Sentinel,管道和编码器。

    Spring-boot-data-redis 提供了几个Redis操作模板, 例如: RedisTemplate、StringRedisTemplate、ReactiveRedisTemplate、 ReactiveStringRedisTemplate、RedisKeyValueTemplate等。下面对各模板的使用进行详细讲解。

    三、 Spring Boot 与Redis集成

    1. 创建工程spring-boot-nosql-redis
      在这里插入图片描述

      启动类:

      com.mirson.spring.boot.nosql.redis.startup.NosqlRedisApplication

      @SpringBootApplication
      @ComponentScan(basePackages = {"com.mirson"})
      public class NosqlRedisApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(NosqlRedisApplication.class, args);
          }
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    2. MAVEN依赖

      pom.xml

      <dependencies>
      
          
          <dependency>
              <groupId>org.springframework.bootgroupId>
              <artifactId>spring-boot-starter-data-redisartifactId>
          dependency>
      
      dependencies>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      默认采用父依赖的2.1.6.RELEASE版本。

    3. 配置文件

      application.yml

      server:
        port: 11612
      spring:
        application:
          name: nosql-redis
        # Redis 缓存配置
        redis:
          host: 127.0.0.1
          password:
          port: 6379
          jedis:
            pool:
              # 最大连接数
              max-active: 16
              # 空闲最大连接数
              max-idle: 4
              # 空闲最小连接数
              min-idle: 2
              # 连接分配最长等待时间
              max-wait: 500
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

      配置Redis主机连接信息, 配置连接池信息, 包含最大连接数、空闲最大连接数、空闲最小连接数和连接分配最长等待时间, 根据项目实际需要进行配置。

    4. Java Config 配置

      com.mirson.spring.boot.nosql.redis.config.RedisConfiguration

      @Configuration
      @EnableCaching
      public class RedisConfiguration {
      
          /**
           * Redis 缓存配置
           * @return
           */
          @Bean
          public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
              RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
              /// 配置KEY序列化方式
              redisTemplate.setKeySerializer(new StringRedisSerializer());
              redisTemplate.setHashKeySerializer(new StringRedisSerializer());
              // 配置VALUE的序列化方式
              redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
              redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
              redisTemplate.setConnectionFactory(redisConnectionFactory);
              return redisTemplate;
          }
      
          /**
           * 设置默认超时时间
           * @param redisConnectionFactory
           * @return
           */
          @Bean
          public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
              // 超时时间默认设为24小时
              Duration expiration = Duration.ofSeconds(3600 * 24);
              return RedisCacheManager.builder(redisConnectionFactory)
                      .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(expiration)).build();
          }
      
          /**
           * 设置Redis 响应式操作模板
           * @param factory
           * @return
           */
          @Bean
          ReactiveStringRedisTemplate reactiveStringRedisTemplate(ReactiveRedisConnectionFactory factory) {
              return new ReactiveStringRedisTemplate(factory);
          }
      
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 要开启@EnableCaching注解, 否则redisTemplate配置不能正在生效。
      • 配置RedisTemplate, 主要是key和value的序列化方式,key采用string序列化, 便于查询。
      • CacheManager配置, 指定超时时间为24小时。CacheManager是Spring Cache的接口, 可以基于不同缓存实现, 如Redis、Memcached等。不作配置, Spring data Redis 启动器也会自动加载。
      • ReactiveStringRedisTemplate是响应式操作模板, 接下来要使用, 需要先作配置。

    四、 Spring Boot 集成Redis之CacheManager使用

    1. 提供缓存更新操作接口

      com.mirson.spring.boot.nosql.redis.controller.RedisController

          /**
           * cache manager 缓存更新操作
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/cache/put")
          public String cachePut(String key, String value) {
              cacheManager.getCache(CACHE_NAME).put(key, value);
              return "cacheManager, put redis key: " + key + ", value: " + value;
          }
      
          /**
           * cache manager 缓存删除操作
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/cache/evict")
          public String cacheEvict(String key) {
              cacheManager.getCache(CACHE_NAME).evict(key);
              return "cacheManager, evict redis key: " + key ;
          }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24

      提供缓存的更新与删除操作接口, CacheManager缓存使用, 需先指定一个Cache名称,其实也就是Redis的Key前缀, 该Cache所有缓存key都会放在其下面。

    2. 提供缓存查找接口

      com.mirson.spring.boot.nosql.redis.controller.RedisController

      /**
           * cache manager 缓存查找
           * @param key
           * @return
           */
          @GetMapping("/cache/find")
          public String cacheFind(String key) {
              Set<String> keys = redisTemplate.keys(CACHE_NAME + "::" +  key + "*");
              StringBuffer result = new StringBuffer();
              if (null != keys && !keys.isEmpty()) {
                  Cache cache = cacheManager.getCache(CACHE_NAME);
                  keys.forEach( k -> {
                      // 获取缓存
                      Cache.ValueWrapper valueWrapper = cache.get(k.replaceAll(CACHE_NAME + "::", ""));
                      if (cache != null && valueWrapper != null) {
                          String value = (String)valueWrapper.get();
                          result.append("key: ").append(k).append(", value: ").append(value).append("
      "
      ); } }); }else { result.append("not found."); } return result.toString().replaceAll("
      $"
      , ""); }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      CacheManager自身没有提供比较完善的Key查询接口, 如果需要查询Cache下面的所有key, 可以通过redisTemplate的keys接口来帮助实现。

    3. 测试验证

      1. 增加三条缓存记录

        商品: goods1, 价格: 10.11

        http://127.0.0.1:11612/cache/put?key=goods1&value=10.11

        商品: goods2, 价格: 10.12

        http://127.0.0.1:11612/cache/put?key=goods2&value=10.12

        商品: goods3, 价格: 10.13

        http://127.0.0.1:11612/cache/put?key=goods3&value=10.13

      2. 查看缓存记录

        http://127.0.0.1:11612/cache/find?key=goods
        在这里插入图片描述

        能够正常获取刚才设置的三条缓存数据。

      3. 删除缓存记录

        将第二条商品记录删除

        http://127.0.0.1:11612/cache/evict?key=goods2

        重新查看缓存记录
        在这里插入图片描述

        正确删除了第二条商品记录。

    五、 Spring Boot 集成Redis之模板使用

    RedisTemplate有多种, 每个模板的key和value的序列化方式存在不同, 其他接口功能基本类似, 这里就以常用的stringRedisTemplate作为讲解。

    1. 提供缓存更新操作接口

      com.mirson.spring.boot.nosql.redis.controller.RedisController

          /**
           * string template 缓存更新操作
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/template/put")
          public String stringPut(String key, String value) {
              stringRedisTemplate.opsForValue().set(key, value);
              return "stringTemplate, put redis key: " + key + ", value: " + value;
          }
      
          /**
           * string template 缓存更新操作
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/template/del")
          public String stringDel(String key, String value) {
              stringRedisTemplate.delete(key);
              return "stringTemplate, delete redis key: " + key;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    2. 提供缓存查找接口

          /**
           * template 缓存查找
           * @param key
           * @return
           */
          @GetMapping("/template/find")
          public String templateFind(String key) {
              Set<String> keys = stringRedisTemplate.keys(  key + "*");
              StringBuffer result = new StringBuffer();
              if (null != keys && !keys.isEmpty()) {
                  keys.forEach( k -> {
                      String value = stringRedisTemplate.opsForValue().get(k);
                      result.append("key: ").append(k).append(", value: ").append(value).append("
      "
      ); }); }else { result.append("not found."); } return result.toString().replaceAll("
      $"
      , ""); }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    3. 测试验证

      1. 增加三条缓存记录

        用户:user1,年龄:25

        http://127.0.0.1:11612/template/put?key=user1&value=25

        用户:user2,年龄:26

        http://127.0.0.1:11612/template/put?key=user2&value=26

        用户:user3,年龄:27

        http://127.0.0.1:11612/template/put?key=user3&value=27

      2. 查看缓存记录
        http://127.0.0.1:11612/template/find?key=user
        在这里插入图片描述

        正常获取设置的三条缓存记录。

      3. 删除缓存记录

        将第二条用户记录删除

        http://127.0.0.1:11612/template/del?key=user2

        重新查询缓存记录
        在这里插入图片描述

      正确删除第二条用户记录。

    六、 Spring Boot 集成Redis之响应式使用

    Spring Data Redis 是可以支持响应式编程, 通过Reactive模式, 设置回调方法, 能够让线程处理其他事务, 不会因为Redis操作阻塞程序运行。

    1. 提供缓存更新操作接口

      com.mirson.spring.boot.nosql.redis.controller.RedisController

          /**
           * redis reactive 更新缓存
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/reactive/put")
          public String reactivePut(String key, String value) {
              Mono result = reactiveStringRedisTemplate.opsForValue().set(key, value);
              String message = "reactive, put redis key: " + key + ", value: " + value;
              result.subscribe(log::info);
              log.info(message);
              return message ;
          }
      
          /**
           * redis reactive 删除缓存
           * @param key
           * @param value
           * @return
           */
          @GetMapping("/reactive/del")
          public String reactiveDel(String key, String value) {
              Mono result = reactiveStringRedisTemplate.delete(key);
              String message = "reactive, delete redis key: " + key + ", value: " + value;
              result.subscribe(log::info);
              log.info(message);
              return message ;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29

      提供了reactive模式的更新与删除缓存接口, 查询接口仍采用template模板方式查询。

      reactive为异步模式, 通过回调方法处理结果, 注意日志打印位置, 验证时, 通过控制台日志输出,可以看到为异步处理方式。

    2. 测试验证

      1. 增加三条缓存记录

        省份:province1, 名称: 广东省
        http://127.0.0.1:11612/reactive/put?key=province1&value=%E5%B9%BF%E4%B8%9C%E7%9C%81

        省份:province2,名称: 广西省
        http://127.0.0.1:11612/reactive/put?key=province2&value=%E5%B9%BF%E8%A5%BF%E7%9C%81
        省份:province3,名称: 江西省
        http://127.0.0.1:11612/reactive/put?key=province3&value=%E6%B1%9F%E8%A5%BF%E7%9C%81

      2. 查看控制台日志
        在这里插入图片描述

        可以看到, 日志输出顺序已经发生变化,

      3. 查看缓存记录

        http://127.0.0.1:11612/template/find?key=province
        在这里插入图片描述

        从缓存里面正常获取三条记录。

    七、总结

    Spring Boot Starter Data Redis 对Redis作了比较完善的封装,功能支持比较丰富, 通过Template模板, 可以定制所需的各种数据结构与序列化方式, Reactive封装对响应式编程提供良好支持, 底层基于Lettuce实现, 性能也有较好的保障,本章基于Spring Data Redis所提供的不同使用模式作了讲解,里面还有很多丰富的API接口功能, 有兴趣可以再做深入研究。

    附: 所有源码都已上传, 如有需要, 可在博主的资源中下载。

  • 相关阅读:
    过去5年,PolarDB云原生数据库是如何进行性能优化的?
    线性回归算法原理
    简易版的新闻应用
    Linux下Couchbase的安装&升级&维护最佳指南
    微信截图不能截微信界面
    【附源码】Python计算机毕业设计木棉堂水果电商平台
    磺酸修饰/单分散氢氧化钙/聚苯乙烯微球/载对苯二酚聚苯乙烯-二乙烯苯交联微球的性能
    如何利用AirDroid远程访问安卓设备屏幕?
    嵌入式Linux系统中ARM汇编语言的使用方法
    【机器学习】阿里云天池竞赛——工业蒸汽量预测(3)
  • 原文地址:https://blog.csdn.net/hxx688/article/details/126328417