1.分布式缓存概述
1.1.什么是分布式缓存
通常将数据从数据库中同步一份到内存中,客户端直接从内存中查询数据,减少了和数据库的交互次数,提高查询性能(内存读写很快),减轻数据库的压力
1.2.那些数据适合缓存
-
经常查询的热点数据
-
不经常变的数据(数据变化会导致缓存中的数据跟着变,如果比较频繁,性能开销比较大)
1.3.缓存执行流程
-
每次查询,先看缓存是否有数据 , 如果有:直接返回
-
如果缓存没有数据,去数据库查询数据
-
把数据同步一份到缓存
-
返回数据
【注意
】数据库数据被修改,缓存要清空,或者重置
1.3.为什么要分布式缓存
-
在集群环境中,每个应用都有一个本地缓存,当缓存发生修改会造成缓存不同步问题
-
本地缓存本身要占用应用的内存空间
1.4.分布式缓存方案
使用Redis作为共享缓存 ,解决缓存不同步问题,Redis是独立的服务,缓存不用占用应用本身的内存空间
2.分布式缓存实战
SpringBoot提供了整合Redis的方案,我们使用spring-boot-starter-data-redis包就可以很方便的操作Redis了
1.导入依赖
<!--整合Redis , 底层可以用jedis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2.配置Redis
spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool:
max-wait: 2000ms
min-idle: 2
max-idle: 8
3.Redis序列化配置
//缓存的配置
@Configuration
public class RedisConfig {
@Resource
private RedisConnectionFactory factory;
//使用JSON进行序列化
@Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
//JSON格式序列化
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//key的序列化
redisTemplate.setKeySerializer(genericJackson2JsonRedisSerializer);
//value的序列化
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
//hash结构key的虚拟化
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//hash结构value的虚拟化
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
}
}
SpringCache缓存
SpringCahce对缓存流程进行了简化封装,提供了一些注解,我们通过简单的打注解就能实现缓存的添加,修改,删除等,注解如下:
-
@Cacheable:触发缓存写入。 @Cacheable(cacheNames=“books”,key=”’book1’”) // books::book1
-
@CacheEvict:触发缓存清除。
-
@CachePut:更新缓存(不会影响到方法的运行)。
-
@Caching:重新组合要应用于方法的多个缓存操作。
-
@CacheConfig:设置类级别上共享的一些常见缓存设置
Cache缓存实战
2.1.导入依赖
这里配合Redis实现缓存,前面已经导入了redis的包,这里不再导入
2.2.配置SpringCache 拷贝配置类
继承 CachingConfigurerSupport 对SpringCache进行配置
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
@Resource
private RedisConnectionFactory factory;
/**
* 自定义生成redis-key , 类名.方法名
*/
@Override
@Bean
public KeyGenerator keyGenerator() {
return (o, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName()).append(".");
sb.append(method.getName()).append(".");
for (Object obj : objects) {
sb.append(obj.toString());
}
System.out.println("keyGenerator=" + sb.toString());
return sb.toString();
};
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
// 用于捕获从Cache中进行CRUD时的异常的回调处理器。
return new SimpleCacheErrorHandler();
}
//缓存管理器
@Bean
@Override
public CacheManager cacheManager() {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues() //不允许空值
.serializeValuesWith(RedisSerializationContext.SerializationPair
//值使用JSON序列化
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
}
}
2.3.开启SpringCache
在启动类加注解:@EnableCaching
2.4.缓存实战
【特别注意
】缓存注解不能加在内部方法上,比如:方法A调用方法B,给方法B加上缓存注解会失效,因为内部方法调用代理会失效。在A方法上打注解即可。
@CacheConfig(cacheNames = "black") 类上通用配置
@CacheEvict(key = "'phone'") 增删改方法上
@Cacheable(key = "'phone'") 需要缓存数据的方法上