一、redis简介
redis是一个非关系型数据库,它能够存储字符串和五种不同类型之间的值的映射,key值只能字符串,value可以是五种不同数据类型:字符串、列表、集合、哈希、有序集合。redis相对于其他数据库,是基于内存的操作,因此其存取速度极快,被广泛应用于缓存方向。除了缓存之外,redis还常被用于分布式架构中锁的实现,用于保证多机多线程中共享资源的线程安全问题。这篇文章主要对redis在缓存中的具体应用做详细介绍,做一个springboot整合redis的简单实践。
二、redis下载安装
实验系统:mac
(1)redis下载地址:http://redis.io/download
(2)解压:tar -zvxf redis-6.2.3.tar.gz
(3)将解压后的文件夹放到 /usr/local目录下:sudo mv redis-6.2.3 /usr/local/redis-6.2.3
(4)cd /usr/local/redis-6.2.3
(5)sudo make test
(6)sudo make install
(7)启动redis: redis-server
三、pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
四、application.yml配置redis
五、编写redisConfig配置文件
@Configuration
@EnableCaching
public class CacheConfig {
public static final String DEFAULT_SEPARATOR = "#";
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
return new MyCacheManager(redisCacheWriter, defaultCacheConfig);
}
class MyCacheManager extends RedisCacheManager{
public MyCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
}
@Override
protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
Duration ttl = getTtlByName(name);
if(ttl != null){
cacheConfig = cacheConfig.entryTtl(ttl);
}
return super.createRedisCache(name, cacheConfig);
}
private Duration getTtlByName(String name) {
String[] separate = name.split(DEFAULT_SEPARATOR);
if(separate.length > 1){
String ttl = separate[1];
System.out.println(ttl);
if(!StringUtils.isEmpty(ttl)){
return Duration.ofSeconds(Long.parseLong(ttl));
}
}
return null;
}
}
}
自定义一个内部类实现从@Cacheable注解中的cacheName参数中提取过期时间,实现过期时间可配置。
注意@EnableCache注解可以选择springboot项目主程序入口处加上或者redis的这个配置类加上,不加则redis不能生效。
六、使用@Cacheable实现缓存
@Service
public class TestService {
@Cacheable(key = "'getResult' + #appId", cacheNames = "string#10")
public String getResult(Integer appId){
System.out.println(22222);
return "liuleiwudi";
}
}
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@PostMapping("/writeMessage")
public void writeMessage() {
// Producer.sendMessage("topic", "tag", "hello, RocketMq");
System.out.println(testService.getResult(3));
}
}
基于此,可以实现一个自定义过期时间的redis缓存功能,上面程序的过期时间为10s
七、@CachePut,@Cacheable ,@CacheEvict区别
(1)@CachePut:被@CachePut修饰的方法每次被调用都会被执行,执行结果按照@CachePut中参数配置的cache块名称和key进行缓存,简单来说就是只缓存不用
(2)@Cacheable:使用缓存的逻辑注解,被@Cacheable修饰的方法每次被调用都会去检查一下缓存中是否有对应的值,如果有,则直接拿出来执行,如果没有,则执行方法体,并将结果写到缓存中
(3)@CacheEvict:删除缓存中对应的值
八、@Cacheable注解中value,cacheName和key,condition和unless的区别
value和cacheName都是指cache块的名称,二者选其一使用即可,cache块中的数据以键值对存储,以key进行标识
condition表示满足条件走缓存逻辑
unless表示不满足条件才走缓存逻辑
另外,redis也经常用在分布式架构中分布式锁的实现,持续学习中,后面有机会也写一个小的demo