Docker安裝Redis(如果已安裝請?zhí)^這一步)
1、拉取Redis鏡像(默認(rèn)最新版本)
docker pull redis
如果下載比較慢的話建議配置阿里云鏡像
查看阿里云鏡像:阿里云官網(wǎng)-->產(chǎn)品-->搜索容器鏡像服務(wù)-->管理控制臺

左側(cè)邊欄下方的鏡像加速器:

點(diǎn)進(jìn)去可以看到下方有一個加速地址和使用方法:

把大括號及大括號里的內(nèi)容復(fù)制進(jìn)/etc/docker/daemon.json文件中:
vim /etc/docker/daemon.json
重新加載daemon文件和docker即添加鏡像成功
systemctl daemon-reload
systemctl restart docker
2、安裝完redis鏡像后查看是否安裝成功
docker images
3、運(yùn)行redis
docker run -d -p 6379:6379 --name myredis redis
4、查看是否運(yùn)行成功
docker ps
快速使用Redis
1、導(dǎo)入Redis的依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、添加配置文件
# Redis數(shù)據(jù)庫索引(默認(rèn)為0)
spring.redis.database=0
# Redis服務(wù)器地址(默認(rèn)為localhost)
spring.redis.host=localhost
# Redis服務(wù)器連接端口(默認(rèn)為6379)
spring.redis.port=6379
# Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
# 連接池最大連接數(shù)(使用負(fù)值表示沒有限制) 默認(rèn) 8
spring.redis.lettuce.pool.max-active=8
# 連接池最大阻塞等待時間(使用負(fù)值表示沒有限制) 默認(rèn) -1
spring.redis.lettuce.pool.max-wait=-1
# 連接池中的最大空閑連接 默認(rèn) 8
spring.redis.lettuce.pool.max-idle=8
# 連接池中的最小空閑連接 默認(rèn) 0
spring.redis.lettuce.pool.min-idle=0
3、添加Redis配置類
自定義一個RedisCacheManager
@Configuration
public class MyRedisConfig {
@Bean
public RedisCacheManager defaultRedisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(6)) // 設(shè)置緩存過期時間為6小時
.disableCachingNullValues() // 禁用緩存空值,不緩存null校驗(yàn)
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
GenericJackson2JsonRedisSerializer())); // 設(shè)置CacheManager的值序列化方式為json序列化
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build(); // 設(shè)置默認(rèn)的cache組件
}
}
4、開啟基于注解的緩存:@EnableCaching
@EnableCaching
@SpringBootApplication
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
5、使用@Cacheable注解進(jìn)行緩存
@Cacheable主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存
@Service
public class BlogServiceImpl implements BlogService {
@Autowired
private BlogMapper blogMapper;
@Cacheable(cacheNames = "totalBlog")
@Override
public Long getTotalBlogs() {
return blogMapper.getTotalBlogs();
}
}
原理:
- 方法運(yùn)行之前,先去查詢Cache(緩存組件),按照cacheNames指定的名字獲取
- 沒有查到緩存就調(diào)用目標(biāo)方法,并將目標(biāo)方法的返回的結(jié)果放進(jìn)緩存中
- 查到了緩存就直接使用緩存,就不會再去數(shù)據(jù)庫查詢數(shù)據(jù)
執(zhí)行完以上步驟即使用完成。
踩過的坑:反序列化獲取數(shù)據(jù)發(fā)生類型轉(zhuǎn)換異常
往Redis中存儲Long類型的數(shù)據(jù)時,反序列化時發(fā)生Integer轉(zhuǎn)Long類型轉(zhuǎn)換異常;

我明明存的是Long類型的數(shù)據(jù)啊,怎么存進(jìn)去就變成Integer類型了呢?
這要從自定義CacheManager說起......
@Configuration
public class MyRedisConfig {
@Bean
public RedisCacheManager defaultRedisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(6)) // 設(shè)置緩存過期時間為6小時
.disableCachingNullValues() // 禁用緩存空值,不緩存null校驗(yàn)
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
GenericJackson2JsonRedisSerializer())); // 設(shè)置CacheManager的值序列化方式為json序列化
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build(); // 設(shè)置默認(rèn)的cache組件
}
}
我們自定義CacheManager的時候,使用的是GenericJackson2JsonRedisSerializer序列化器,而GenericJackson2JsonRedisSerializer在反序列化的時候會統(tǒng)一將緩存反序列化為Object類型,又因?yàn)槲覀兇娴闹凳切∮?code>Integer.MAX_VALUE的,自然而然的就轉(zhuǎn)為了Integer。
而我們要解決這種情況的話,只有在存數(shù)據(jù)的時候就指定數(shù)據(jù)類型,可以使用Jackson2JsonRedisSerializer:
@Bean
public RedisCacheManager longRedisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(6)) // 設(shè)置緩存過期時間為6小時
.disableCachingNullValues() // 禁用緩存空值,不緩存null校驗(yàn)
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
Jackson2JsonRedisSerializer<Long>(Long.class))); // 設(shè)置CacheManager的值序列化方式為json序列化,指定我們所存的數(shù)據(jù)為Long類型,取出時自然會幫我們反序列化成Long類型
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build(); // 設(shè)置默認(rèn)的cache組件
}
當(dāng)存在兩個或兩個以上的RedisCacheManager的時候,我們必須在某個RedisCacheManager上標(biāo)注@Primary注解,來表示這個RedisCacheManager是主要的;當(dāng)然在使用緩存注解來進(jìn)行緩存的時候,如果需要使用指定的RedisCacheManager,就可以使用cacheManager屬性進(jìn)行指定,如果沒有指定,就默認(rèn)使用標(biāo)注了@Primary注解的RedisCacheManager
@Cacheable(cacheNames = "totalBlog",cacheManager = "longRedisCacheManager")
@Override
public Long getTotalBlogs() {
return blogMapper.getTotalBlogs();
}