【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);
        }
    }
    
    
  2. MAVEN依赖

    pom.xml

    <dependencies>
    
        <!-- Spring boot data redis 组件依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    
    </dependencies>
    

    默认采用父依赖的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
    

    配置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);
        }
    
    
    }
    
    • 要开启@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 ;
        }
    
    

    提供缓存的更新与删除操作接口, 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("<br>");
                    }
                });
            }else {
                result.append("not found.");
            }
            return result.toString().replaceAll("<br>$", "");
        }
    
    

    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;
        }
    
  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("<br>");
                });
            }else {
                result.append("not found.");
            }
            return result.toString().replaceAll("<br>$", "");
        }
    
  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 ;
        }
    

    提供了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接口功能, 有兴趣可以再做深入研究。

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦神-mirson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值