Redis 实践
前言
这篇文章主要介绍 Redis 在项目中的使用,实现常见的一些功能。
需要 Redis 基础知识,可以参考之前的文章:Redis 基础
Session 共享分布式登录
场景
项目中单点登录,将用户信息存放到 Session 中,
存在这样的问题:为什么用户在服务器 A 登录,向服务器 B 发请求时,服务器不认识该用户?
原因:用户信息在 A 的内存中,B 和 A 的内存是独立的两个空间。
解决:共享存储,实现分布式登录
Redis 实现
代码很简单,学习思想~
引入 redis,为了操作 redis
1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.4</version>
</dependency>引入 spring-session 和 redis 的整合,为了自动将 session 存储到 redis
1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.6.4</version>
</dependency>修改 spring-session 的存储配置
1
2
3spring:
session:
store-type: redis配置 redis
1
2
3
4
5spring:
redis:
host: host
port: port
database: 0~15
数据缓存
场景
当我们的数据量比较大时,直接读取数据库中的数据会非常慢(MySQL 存储到磁盘)。
解决方法:把数据读取出来然后保存到更快的介质,例如内存,实现更快地读写。
Redis 刚好是一个高性能的 K/V 内存存储系统~
Redis 实现
整合
引入 redis
1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.4</version>
</dependency>配置 redis
1
2
3
4
5spring:
redis:
host: host
port: port
database: 0~15配置 RedisTemplate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* @author ShameYang
* @date 2024/5/22 16:43
* @description RedisTemplate 配置
*/
public class RedisTemplateConfig {
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
//创建 RedisTemplate 对象
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//设置连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
//设置 Key 的序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
//创建 Json 序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置 Value 的序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
}
数据缓存
设计缓存 key
systemId:moduleId:func:options
修改查询数据的方法:有缓存就读取,没有则读取数据库,写到缓存中(一定要设置过期时间!!!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16String redisKey = String.format("friendhub:user:recommend:%s", loginUser.getId());
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
// 有缓存,直接读取
Page<User> userPage = (Page<User>) valueOperations.get(redisKey);
if (userPage != null) {
return;
}
// 没有缓存,查数据库
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
userPage = userService.page(new Page<>(pageNum, pageSize), queryWrapper);
// 写缓存,10s过期
try {
valueOperations.set(redisKey, userPage, 10000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error("redis set key error", e);
}
定时任务/数据预热
我们只进行了数据缓存,但是存在一个问题:第一个访问的用户会读取数据库,加载慢,体验很差
数据预热,可以解决这个问题,让用户的访问始终很快。
需要根据具体的场景决定是否进行数据预热!!
定时任务参考文章:SpringBoot 实现定时任务-@Scheduled
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ShameYang's Blog!