image.pngRedis 缓存

ykkj-spring-boot-starter-redis技术组件,使用 Redis 实现缓存的功能,它有 2 种使用方式:

  • 编程式缓存:基于 Spring Data Redis 框架的 RedisTemplate 操作模板
  • 声明式缓存:基于 Spring Cache 框架的 @Cacheable 等等注解

    1. 编程式缓存

    ```xml org.redisson redisson-spring-boot-starter
  1. 由于 Redisson 提供了分布式锁、队列、限流等特性,所以使用它作为 Spring Data Redis 的客户端。
  2. <a name="wI0Gb"></a>
  3. ### 1.1 Spring Data Redis 配置
  4. application-local.yaml配置文件中,通过 spring.redis 配置项,设置 Redis 的配置。如下图所示:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/28522586/1652262936059-9fb52459-ab21-4f73-878d-d7212f4e63ca.png#clientId=u4e04adb9-70f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u5002c208&margin=%5Bobject%20Object%5D&name=image.png&originHeight=313&originWidth=805&originalType=url&ratio=1&rotation=0&showTitle=false&size=44351&status=done&style=none&taskId=u6fe8b147-3f9c-4920-8601-0bee8544d21&title=)<br />② 在 framework/redis/config/YkkjRedisAutoConfiguration.java配置类,设置使用 JSON 序列化 value 值。如下图所示:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/28522586/1652262936132-14462405-9114-4454-92bb-1151ea3cd06e.png#clientId=u4e04adb9-70f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u67e71684&margin=%5Bobject%20Object%5D&name=image.png&originHeight=478&originWidth=909&originalType=url&ratio=1&rotation=0&showTitle=false&size=96875&status=done&style=none&taskId=u4bb3b02b-a4b6-49ef-88d0-85b9dd43c93&title=)
  5. <a name="b2CLT"></a>
  6. ### 1.2 实战案例
  7. 以登录用户的缓存来举例子,讲解项目中是如何使用 Spring Data Redis 框架的。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/28522586/1652262936107-db631b3e-c8c7-4f86-8103-723e6a3396ee.png#clientId=u4e04adb9-70f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=udbd55259&margin=%5Bobject%20Object%5D&name=image.png&originHeight=54&originWidth=813&originalType=url&ratio=1&rotation=0&showTitle=false&size=17338&status=done&style=none&taskId=ub5122810-f244-4131-97ef-ff3741497fa&title=)
  8. <a name="E3jOx"></a>
  9. #### 1.2.1 引入依赖
  10. ykkj-module-system-biz 模块中,引入 ykkj-spring-boot-starter-redis 技术组件。如下所示:
  11. ```xml
  12. <dependency>
  13. <groupId>cn.iocoder.boot</groupId>
  14. <artifactId>yudao-spring-boot-starter-redis</artifactId>
  15. </dependency>

1.2.2 LoginUser

新建 framework/security/core/LoginUser.java类,登录用户的缓存。代码如下:
image.png
友情提示:
一般情况下,每个缓存对应的类,创建在对应模块的 dal/dataobject 包下。

1.2.3 RedisKeyConstants

每个 ykkj-module-xxx 模块,都有一个 RedisKeyConstants 类,定义该模块的 Redis Key 的信息。目的是,避免 Redis Key 散落在 Service 业务代码中,像对待数据库的表一样,对待每个 Redis Key。通过这样的方式,如果我们想要了解一个模块的 Redis 的使用情况,只需要查看 RedisKeyConstants 类即可。
因此,在 ykkj-module-system 模块的 module/system/dal/redis/RedisKeyConstants.java类中,新建 LoginUser 对应的 Redis Key 定义 LOGIN_USER。如下图所示:
image.png
友情提示:
framework/redis/core/RedisKeyDefine.java是 Redis Key 定义类,填写 Key 模板、Value 在 Redis 中的类型、Value 在 Java 中的类型、过期时间等信息。

1.2.4 LoginUserRedisDAO

新建 system/dal/redis/auth/LoginUserRedisDAO.java类,是 LoginUser 的 RedisDAO 实现。代码如下:
image.png

1.2.5 UserSessionServiceImpl

在 /module/system/service/auth/UserSessionServiceImpl.java中,只要注入 LoginUserRedisDAO Bean,非常简洁干净的进行 LoginUser 的缓存操作,无需关心具体的实现。代码如下:
image.png

2. 声明式缓存

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

相比来说 Spring Data Redis 编程式缓存,Spring Cache 声明式缓存的使用更加便利,一个 @Cacheable 注解即可实现缓存的功能。示例如下:

@Cacheable(value = "users", key = "#id")
UserDO getUserById(Integer id);

2.1 Spring Cache 配置

① 在 application.yaml配置文件中,通过 spring.redis 配置项,设置 Redis 的配置。如下图所示:
image.png
② 在 framework/redis/config/YudaoCacheAutoConfiguration.java配置类,设置使用 JSON 序列化 value 值。如下图所示:
image.png

2.2 常见注解

2.2.1 @Cacheable 注解

@Cacheable注解:添加在方法上,缓存方法的执行结果。执行过程如下:

  • 1)首先,判断方法执行结果的缓存。如果有,则直接返回该缓存结果。
  • 2)然后,执行方法,获得方法结果。
  • 3)之后,根据是否满足缓存的条件。如果满足,则缓存方法结果到缓存。
  • 4)最后,返回方法结果。

    2.2.2 @CachePut 注解

    @CachePut注解,添加在方法上,缓存方法的执行结果。不同于 @Cacheable 注解,它的执行过程如下:

  • 1)首先,执行方法,获得方法结果。也就是说,无论是否有缓存,都会执行方法。

  • 2)然后,根据是否满足缓存的条件。如果满足,则缓存方法结果到缓存。
  • 3)最后,返回方法结果。

    2.2.3 @CacheEvict 注解

    @CacheEvict注解,添加在方法上,删除缓存。

    2.3 实战案例

    在 /module/infra/service/test/TestDemoServiceImpl.java中,项目提供了一个 Spring Cache 的示例,采用【被动读】的方案。原因是:
    image.png

  • 【被动读】相对能够保证 Redis 与 MySQL 的一致性

  • 绝大数数据不需要放到 Redis 缓存中,采用【主动写】会将非必要的数据进行缓存

① 执行 #getTestDemo(…) 方法,从 MySQL 读取数据后,向 Redis 写入缓存。如下图所示:
image.png
② 执行 #updateTestDemo(…) 方法,在更新 MySQL 数据后,从 Redis 删除缓存。如下图所示:
image.png

3. Redis 监控

ykkj-module-infra 的 redis模块,提供了 Redis 监控的功能。
点击 [基础设施 -> Redis 监控] 菜单,可以查看到 Redis 的基础信息、命令统计、内存信息、Key 列表。如下图所示:
image.png