✏️作者:银河罐头
📋系列专栏:JavaEE
🌲“种一棵树最好的时间是十年前,其次是现在”
目录
- 安装 Redis
- redis 的数据类型和使用
- 字符串类型
- 字典类型
- 列表类型
- 集合类型
- 有序集合类型
- SpringBoot 集成 Redis
- 添加 redis 依赖
- 配置 redis
- 手动操作 redis
- Spring Session 持久化
- 添加依赖
- 设置配置文件
- 存储和读取 session
- 持久化
安装 Redis
安装 FinalShell
https://zhuanlan.zhihu.com/p/430110272?utm_id=0
1.yum 安装 redis
使用以下命令,直接将 redis 安装到 linux 服务器:
yum -y install redis
2.启动 redis 使用以下命令,以后台运行方式启动 redis:
redis-server /etc/redis.conf &
3.操作 redis
使用以下命令启动 redis 客户端:
redis-cli
4.设置远程连接
1.将 redis 配置文件下载到本地:redis 配置文件是 linux 下的 /etc/redis.conf ;
2.将 redis.conf 中的 “bind 127.0.0.1”注释掉;
3.将 redis.conf 中的“protected-mode yes” 改为“protected-mode no”;
4.将修改后的 redis.conf 上传至 liunx 下的 /etc 目录;
5.使用命令“redis-cli shutdown”先关闭 redis 服务,再使用“redis-server /etc/redis.conf &”启动 redis 服务。
redis 的数据类型和使用
Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库。
https://redis.io/commands/
Redis 有 5 大基础数据类型:
String——字符串类型
Hash——字典类型
List——列表类型
Set——集合类型
ZSet——有序集合类型
字符串类型
127.0.0.1:6379> set k1 v1 #添加数据
OK
127.0.0.1:6379> get k1 #查询数据
"v1"
127.0.0.1:6379> strlen k1 #查询字符串的长度
(integer) 2
127.0.0.1:6379> set k1 v1 ex 1000 #设置 k1 1000s 后过期
OK
# 相加
127.0.0.1:6379> set num 123
OK
127.0.0.1:6379> incr num
(integer) 124
127.0.0.1:6379> incr num
(integer) 125
127.0.0.1:6379> incrby num 10
(integer) 135
字符串的常⻅使⽤场景:
存放⽤户(登录)信息;
存放⽂章详情和列表信息;
存放和累计⽹⻚的统计信息。
字典类型
字典类型 (Hash) ⼜被成为散列类型或者是哈希表类型,它是将⼀个键值 (key) 和⼀个特殊的“哈希 表”关联起来,这个“哈希表”表包含两列数据:字段和值,它就相当于 Java 中的 Map> 结构。
假如我们使用字典类型来存储⼀篇⽂章的详情信息,存储结构如下图所示:
127.0.0.1:6379> hset myhash key1 value1 #添加数据
(integer) 1
127.0.0.1:6379> hget myhash key1 #查询数据
"value1"
127.0.0.1:6379> HMSET myhash field2 "Hi" field3 "World"
OK
127.0.0.1:6379> HMGET myhash field2
1) "Hi"
127.0.0.1:6379> HMGET myhash field3
1) "World"
列表类型
列表类型 (List) 是⼀个使⽤链表结构存储的有序结构。
127.0.0.1:6379> rpush mylist 1 2 3 4 5
(integer) 5
127.0.0.1:6379> lpop mylist
"1"
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "3"
3) "4"
4) "5"
127.0.0.1:6379> lrange mylist 1 3
1) "3"
2) "4"
3) "5"
列表的典型使⽤场景有以下两个:
消息队列
⽂章列表
redis 作用:
1.存会话信息 session2.缓存
3.分布式锁
集合类型
集合类型 (Set) 是⼀个⽆序并唯⼀的键值集合。
127.0.0.1:6379> sadd myset v1 v2 v3
(integer) 0
127.0.0.1:6379> smembers myset
1) "v3"
2) "v1"
3) "v2"
集合类型的经典使⽤场景如下:
博客关注我的⼈和我关注的⼈都适合⽤集合存储,可以保证⼈员不会重复;
中奖⼈信息也适合用集合类型存储,这样可以保证⼀个⼈不会重复中奖。
有序集合类型
有序集合类型 (Sorted Set) 相⽐于集合类型多了⼀个排序属性 score(分值)。
SpringBoot 集成 Redis
添加 redis 依赖
配置 redis
spring.redis.database=1
spring.redis.port=6379
spring.redis.host=8.130.106.169
spring.redis.password=i0qi8MRFNe144M8n
手动操作 redis
package com.example.redisdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RedisController {
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/save")
public String save(){
redisTemplate.opsForValue().set("userinfo","zhangsan");
return "ok";
}
@RequestMapping("/get")
public Object get(){
return redisTemplate.opsForValue().get("userinfo");
}
@RequestMapping("/save2")
public String save2(){
redisTemplate.opsForHash().put("myhash","username","lisi");
return "ok";
}
@RequestMapping("/get2")
public Object get2(){
return redisTemplate.opsForHash().get("myhash","username");
}
}
Spring Session 持久化
添加依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
设置配置文件
spring.redis.database=2
spring.redis.host=8.130.106.169
spring.redis.password=i0qi8MRFNe144M8n
spring.redis.port=6379
spring.session.store-type=redis
spring.session.redis.flush-mode=on_save
server.servlet.session.timeout=1800
spring.session.redis.namespace=spring:session
存储和读取 session
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
@RequestMapping("/user")
public class UserController {
private static final String SESSION_KEY_USERINFO = "SESSION_KEY_USERINFO";
@RequestMapping("/save")
public String save(HttpSession session){
session.setAttribute(SESSION_KEY_USERINFO,"zhangsan");
return "ok";
}
@RequestMapping("/get")
public Object get(HttpServletRequest request){
HttpSession session = request.getSession();
if(session != null && session.getAttribute(SESSION_KEY_USERINFO)!=null){
return session.getAttribute(SESSION_KEY_USERINFO);
}
return "null";
}
}
- 序列化出错案例
package com.example.demo.entity;
import lombok.Data;
@Data
public class UserInfo {
private int id;
private String username;
private int age;
}
package com.example.demo.controller;
import com.example.demo.entity.UserInfo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
@RequestMapping("/user")
public class UserController {
private static final String SESSION_KEY_USERINFO = "SESSION_KEY_USERINFO";
@RequestMapping("/save")
public String save(HttpSession session){
UserInfo userInfo = new UserInfo();
userInfo.setUsername("zhangsan");
userInfo.setAge(18);
userInfo.setId(1);
session.setAttribute(SESSION_KEY_USERINFO,userInfo);
return "ok";
}
@RequestMapping("/get")
public Object get(HttpServletRequest request){
HttpSession session = request.getSession();
if(session != null && session.getAttribute(SESSION_KEY_USERINFO)!=null){
return session.getAttribute(SESSION_KEY_USERINFO);
}
return "null";
}
}
- 解决方案:
transient 可以设置敏感信息,不显示。
package com.example.demo.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserInfo implements Serializable {
private static String serialVersionUID= "1";
private int id;
private String username;
private transient int age;
}
持久化
所谓的持久化就是将数据从内存保存到磁盘的过程,它的⽬的就是为了防⽌数据丢失。
Redis 持久化的⽅式有以下 3 种:
快照⽅式(RDB, Redis DataBase)将某⼀个时刻的内存数据,以⼆进制的⽅式写⼊磁盘;
⽂件追加⽅式(AOF, Append Only File),记录所有的操作命令,并以⽂本的形式追加到⽂件 中;
混合持久化⽅式:Redis 4.0 之后新增的⽅式,混合持久化是结合了 RDB 和 AOF 的优点,在写⼊ 的时候,先把当前的数据以 RDB 的形式写⼊⽂件的开头,再将后续的操作命令以 AOF 的格式存⼊ ⽂件,这样既能保证 Redis 重启时的速度,⼜能减低数据丢失的⻛险。