055 SpringCache
文章目录
- 缓存一致性
- Spring Cache
- pom.xml
- application.yml
- CubemallProductApplication.java
- SpringCache改造三级分类
- MyCacheConfig.java
- 缓存一致性
缓存一致性
锁
设置过期时间
读写锁
设置过期时间
Spring Cache
1.读模式
缓存穿透:查询一个null数据,解决:开启缓存空数据,spring.cache.redis.cache-null-values=true
缓存击穿:大量并发进来查询一个正好过期的数据,解决:加锁
缓存雪崩:大量的key同时过期 解决:加过期时间,spring.cache.redis.time-to-live=3600000
2.写模式:缓存与数据库一致
读写加锁。
引入Canal,感知到MySQL的更新去更新数据库
读多写多,直接去数据库查询就行
pom.xml
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
application.yml
spring:
cache:
type: redis
redis:
time-to-live: 3600000
cache-null-values: true
CubemallProductApplication.java
package com.xd.cubemall.product;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableCaching
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.xd.cubemall.product.feign")
public class CubemallProductApplication {
public static void main(String[] args) {
SpringApplication.run(CubemallProductApplication.class, args);
}
}
SpringCache改造三级分类
/**
* 使用SpringCache改造三级分类
* @return
*/
@Cacheable(value={"category"}, key = "#root.method.name")
public List<CategoryVo> getLevel1Categorys() {
System.out.println("缓存不命中,查询数据库。。。");
//2.缓存中没有数据,查询数据库,从数据库查询分类数据
List<CategoryVo> categoryJsonFromDb = getCategoryJsonFromWithRedissonLock();
return categoryJsonFromDb;
}
MyCacheConfig.java
package com.xd.cubemall.product.config;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class MyCacheConfig {
@Bean
RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//修改key和value的序列号机制
config = config.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())
);
config = config.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
);
//将配置文件中的所有配置进行生效
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
缓存一致性
/**
* 三级菜单的级联更新 (缓存一致性)
* @param category
*/
@CacheEvict(value = "category", key = "'getLevel1Categorys'")
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);
}