<前文回顾>
<今日更新>
一、开篇整活儿
今儿个咱唠唠 Spring Boot 里头的缓存技术。这玩意儿吧,说大不大,说小不小,整好了是锦上添花,整不好就是火上浇油。你要是刚入门,那可得悠着点儿,别一上来就整得自己"翻车"了。
二、缓存是啥玩意儿?
缓存是提升系统性能的一个利器,说白了就是把一些常用的数据存到内存里头,下次再用的时候直接从内存拿,不用再去数据库查了。Spring Boot 里头默认就集成了缓存技术,用起来贼方便。
1. 缓存的分类
缓存分两种:本地缓存 和分布式缓存。
- 本地缓存:就是把数据存到应用的内存里头,速度快,但是容量有限,而且不能跨应用共享。
- 分布式缓存:就是把数据存到外部的缓存服务器里头,容量大,而且可以跨应用共享,但是速度比本地缓存慢。
2. Redis 是啥玩意儿?
Redis 是一个开源的、高性能的分布式缓存数据库,支持多种数据结构,比如说字符串、哈希、列表、集合啥的。Spring Boot 里头默认就集成了 Redis,用起来贼方便。
三、Spring Boot 集成 Redis
Spring Boot 里头集成 Redis 很简单,只要加个依赖,配个连接信息就行了。
1. 添加依赖
首先,你得在 pom.xml 里头加个 Redis 的依赖。
|--------------------------------------------------------------------------------------------------------------------------------------------|
| XML Code |
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> |
这段代码里头,spring-boot-starter-data-redis 是 Spring Boot 里头的 Redis 依赖。
2. 配置连接信息
然后,你得在 application.properties 里头配个 Redis 的连接信息。
|----------------------------------------------------|
| Properties Code |
| spring.redis.host=localhost spring.redis.port=6379 |
这段代码里头,spring.redis.host 是 Redis 的主机地址,spring.redis.port 是 Redis 的端口号。
3. 使用 RedisTemplate
最后,你可以在代码里头用 RedisTemplate 来操作 Redis。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Autowired private RedisTemplate<String, String> redisTemplate; public void setValue(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return redisTemplate.opsForValue().get(key); } } |
这段代码里头,RedisTemplate 是 Spring Boot 里头的一个类,用来操作 Redis 的。
四、Spring Boot 使用 Redis 缓存
Spring Boot 里头使用 Redis 缓存很简单,只要加个注解就行了。
1. 启用缓存
首先,你得在 Spring Boot 应用里头启用缓存,用 @EnableCaching 注解标记。
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @SpringBootApplication @EnableCaching public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } |
这段代码里头,@EnableCaching 注解启用了缓存。
2. 配置缓存管理器
然后,你得配置缓存管理器,用 @Bean 注解标记。
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Configuration public class CacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()) .build(); } } |
这段代码里头,cacheManager 方法配置了一个 RedisCacheManager,用来管理缓存。
3. 使用 @Cacheable 注解
最后,你可以在 Service 里头用 @Cacheable 注解标记方法,开启缓存。
|---------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Cacheable(value = "myCache", key = "#key") public String getValue(String key) { // 一些复杂的逻辑 return "value"; } } |
这段代码里头,getValue 方法用 @Cacheable 注解标记了,开启了缓存。value 是缓存的名字,key 是缓存的键。
五、Spring Boot 使用 Redis 缓存的坑点
1. 缓存穿透
缓存穿透是指查询一个不存在的数据,缓存里头没有,数据库里头也没有,这样每次查询都会打到数据库上。你要是没处理好,那数据库可就遭殃了。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Cacheable(value = "myCache", key = "#key", unless = "#result == null") public String getValue(String key) { // 一些复杂的逻辑 return null; } } |
这段代码里头,unless = "#result == null" 表示如果返回值为 null,就不缓存。
2. 缓存雪崩
缓存雪崩是指缓存里头的数据大面积失效,导致大量请求直接打到数据库上。你要是没处理好,那数据库可就遭殃了。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Cacheable(value = "myCache", key = "#key", cacheManager = "randomCacheManager") public String getValue(String key) { // 一些复杂的逻辑 return "value"; } } |
这段代码里头,cacheManager = "randomCacheManager" 表示使用随机的缓存管理器,避免缓存同时失效。
3. 缓存击穿
缓存击穿是指缓存里头的数据失效了,导致大量请求直接打到数据库上。你要是没处理好,那数据库可就遭殃了。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Cacheable(value = "myCache", key = "#key", sync = true) public String getValue(String key) { // 一些复杂的逻辑 return "value"; } } |
这段代码里头,sync = true 表示使用同步机制,避免缓存击穿。
专有名词解释
- 缓存:提升系统性能的一个利器,把一些常用的数据存到内存里头,下次再用的时候直接从内存拿。
- 本地缓存:把数据存到应用的内存里头,速度快,但是容量有限,而且不能跨应用共享。
- 分布式缓存:把数据存到外部的缓存服务器里头,容量大,而且可以跨应用共享,但是速度比本地缓存慢。
- Redis:一个开源的、高性能的分布式缓存数据库,支持多种数据结构。
- RedisTemplate:Spring Boot 里头的一个类,用来操作 Redis 的。
- @EnableCaching:Spring Boot 里头的一个注解,用来启用缓存。
- CacheManager:Spring Boot 里头的一个接口,用来管理缓存。
- RedisCacheManager:Spring Boot 里头的一个类,用来管理基于 Redis 的缓存。
- @Cacheable:Spring Boot 里头的一个注解,用来开启缓存。
- 缓存穿透:查询一个不存在的数据,缓存里头没有,数据库里头也没有,导致每次查询都打到数据库上。
- 缓存雪崩:缓存里头的数据大面积失效,导致大量请求直接打到数据库上。
- 缓存击穿:缓存里头的数据失效了,导致大量请求直接打到数据库上。