本文基于官方规范与企业实战整理,无冗余、无错误、结构清晰,覆盖 Redis 基础、命令、SpringBoot 整合、事务锁、秒杀、持久化、主从、哨兵、集群、高可用运维全流程。
目录
- Redis 与 NoSQL 概述
- Redis 安装与配置(Windows/Linux)
- Redis 常用 5 大数据结构与命令
- SpringBoot 整合 Redis(标准版配置)
- Redis 持久化:RDB + AOF
- Redis 事务与锁机制(核心)
- 高并发秒杀实战(解决超卖)
- 缓存三大问题:穿透/击穿/雪崩
- Redis 实现 SSO 单点登录
- 主从复制部署
- 哨兵模式(自动故障转移)
- Redis Cluster 集群部署
- 性能优化与运维规范
1. Redis 与 NoSQL 概述
1.1 什么是 NoSQL
NoSQL = Not Only SQL,泛指非关系型数据库,用于解决高并发、海量数据、高扩展场景。
- 不遵循标准 SQL
- 不支持严格 ACID
- 性能远超关系型数据库
1.2 主流 NoSQL 对比
- Memcache:纯内存、简单 KV、不支持持久化
- Redis:内存为主、支持持久化、多数据结构、企业首选缓存
- MongoDB:文档型、支持复杂查询、适合海量非结构化数据
1.3 Redis 是什么
Redis 是开源、高性能、基于内存的 Key-Value 数据库,支持:
- 多数据结构
- 持久化
- 主从/哨兵/集群
- 事务、Lua 脚本
- 高并发读写(10W QPS+)
典型场景:缓存、秒杀、分布式锁、会话、消息队列、排行榜。
2. Redis 安装与配置
2.1 Linux 安装(标准步骤)
# 安装依赖 yum install -y gcc-c++ # 下载解压 cd /opt wget https://download.redis.io/releases/redis-6.2.5.tar.gz tar -zxvf redis-6.2.5.tar.gz cd redis-6.2.5 # 编译安装 make make install
2.2 后台运行配置
mkdir -p /usr/local/redis/config cp /opt/redis-6.2.5/redis.conf /usr/local/redis/config/ # 修改配置 vim /usr/local/redis/config/redis.conf
核心配置:
daemonize yes # 后台运行 bind 0.0.0.0 # 允许远程 protected-mode no # 关闭保护模式 requirepass 123456 # 密码 port 6379
2.3 启动/关闭/连接
# 启动 redis-server /usr/local/redis/config/redis.conf # 客户端连接 redis-cli -p 6379 -a 123456 # 关闭 redis-cli -a 123456 shutdown
2.4 远程访问配置
- 注释
bind 127.0.0.1 protected-mode no- 防火墙开放 6379 端口
- 设置密码
requirepass
3. Redis 5 大数据结构与常用命令
Redis 默认 16 个库,默认使用 db0。
select 0 # 切换库 dbsize # 查看 key 数量 flushdb # 清空当前库 flushall # 清空所有库 exists key # 是否存在 type key # 查看类型 expire key 10 # 10秒过期 ttl key # 查看剩余时间
3.1 String(字符串)
- 二进制安全,最大 512MB
- 适用:缓存、计数器、分布式锁
set k1 v1 get k1 incr k1 # 自增(计数器) decr k1 # 自减 setnx k1 v1 # 不存在则设置(分布式锁)
3.2 List(列表)
- 双向链表、有序、可重复
- 适用:队列、栈、消息队列
lpush list a b c rpush list d lrange list 0 -1 # 查看全部 lpop list rpop list
3.3 Set(集合)
- 无序、唯一、自动去重
- 适用:去重、交集/并集/差集、抽奖
sadd set a b c smembers set # 查看所有 sismember set a # 是否存在 sinter set1 set2 # 交集 spop set # 随机弹出(抽奖)
3.4 Hash(哈希)
- key-field-value,适合存对象
- 适用:用户信息、商品信息
hset user name zhang age 20 hget user name hgetall user hkeys user hvals user
3.5 ZSet(有序集合)
- 按 score 排序、元素唯一
- 适用:排行榜、热度排序
zadd top 100 java 200 mysql zrange top 0 -1 withscores zrevrange top 0 -1 withscores # 倒序 zrank top java # 排名
4. SpringBoot 整合 Redis(企业标准版)
4.1 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
4.2 application.yml
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
database: 0
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
4.3 RedisTemplate 配置(解决乱码)
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
StringRedisSerializer stringSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSerializer.setObjectMapper(om);
template.setKeySerializer(stringSerializer);
template.setValueSerializer(jacksonSerializer);
template.setHashKeySerializer(stringSerializer);
template.setHashValueSerializer(jacksonSerializer);
template.afterPropertiesSet();
return template;
}
}
4.4 常用操作
// String
redisTemplate.opsForValue().set("name", "zhangsan");
// Hash
redisTemplate.opsForHash().put("user", "age", 20);
// List
redisTemplate.opsForList().leftPush("list", "a");
// Set
redisTemplate.opsForSet().add("set", "a");
// ZSet
redisTemplate.opsForZSet().add("zset", "java", 100);
5. Redis 持久化:RDB + AOF
Redis 基于内存,必须开启持久化防止重启丢数据。
5.1 RDB(快照)
- 定时把内存数据保存为
dump.rdb - 优点:恢复快、文件小
- 缺点:可能丢最后一次快照数据
配置:
save 900 1 save 300 10 save 60 10000 dbfilename dump.rdb dir ./
5.2 AOF(日志追加)
- 记录每一条写命令
- 优点:数据安全
- 缺点:文件大、恢复慢
配置:
appendonly yes appendfilename "appendonly.aof" appendfsync everysec
5.3 企业最佳实践
- 纯缓存:RDB
- 交易/库存/登录:RDB + AOF 同时开启
6. Redis 事务与锁机制(核心)
6.1 Redis 事务特性
- 批量命令入队、顺序执行
- 执行中不被打断
- 不支持回滚
- 不保证严格原子性
6.2 事务命令
MULTI # 开启事务 SET k1 v1 INCR k2 EXEC # 执行 DISCARD # 放弃
6.3 乐观锁 WATCH(高并发必备)
Redis 无悲观锁,只用乐观锁解决并发冲突。
WATCH key:监控 key,若被修改则事务中断- 秒杀、库存扣减必须使用
SET stock 10 WATCH stock MULTI DECR stock EXEC
7. 高并发秒杀实战(解决超卖)
7.1 需求
- 库存 10
- 100 人并发抢购
- 禁止超卖、禁止重复购买
7.2 核心方案
- WATCH 监控库存
- Redis 事务保证原子性
- SessionCallback 批量执行
7.3 最终代码(无超卖)
@RestController
public class SecKillController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@PostMapping("/seckill")
public Result secKill() {
String userId = String.valueOf(new Random().nextInt(10000));
SessionCallback callback = new SessionCallback() {
@Override
public Object execute(RedisOperations operations) {
// 监控库存
stringRedisTemplate.watch("stock");
String stock = stringRedisTemplate.opsForValue().get("stock");
if (stock == null || Integer.parseInt(stock) <= 0) {
return Result.fail("已售罄");
}
// 判断是否重复购买
Boolean bought = stringRedisTemplate.opsForSet().isMember("buy_users", userId);
if (Boolean.TRUE.equals(bought)) {
return Result.fail("已购买");
}
// 开启事务
stringRedisTemplate.multi();
stringRedisTemplate.opsForValue().decrement("stock");
stringRedisTemplate.opsForSet().add("buy_users", userId);
return stringRedisTemplate.exec();
}
};
List result = (List) stringRedisTemplate.execute(callback);
if (result == null || result.isEmpty()) {
return Result.fail("抢购失败");
}
return Result.ok("抢购成功");
}
}
8. 缓存三大问题:穿透/击穿/雪崩
8.1 缓存穿透
- 现象:查不存在的数据,直接打库
- 方案:
- 参数校验
- 缓存空值(短过期)
- 布隆过滤器
8.2 缓存击穿
- 现象:热点 key 过期,大量请求打库
- 方案:
- 热点 key 永不过期
- 分布式锁
8.3 缓存雪崩
- 现象:大量 key 同时过期,数据库压垮
- 方案:
- 过期时间加随机值
- 集群高可用
- 限流降级
9. Redis 实现 SSO 单点登录
9.1 流程
- 登录成功生成 Token
- Token 作为 key,用户信息存入 Redis
- 拦截器校验 Token
- 登出删除 Token
9.2 登录接口
@PostMapping("/login")
public String login(@RequestBody User user, HttpServletResponse response) {
if ("admin".equals(user.getUsername()) && "123".equals(user.getPassword())) {
String token = UUID.randomUUID().toString().replace("-", "");
redisTemplate.opsForValue().set(token, user, 3600, TimeUnit.SECONDS);
response.setHeader("Authorization", token);
return token;
}
return "fail";
}
9.3 登录拦截器
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
if (token == null) return false;
return redisTemplate.hasKey(token);
}
}
10. 主从复制部署
10.1 作用
- 读写分离
- 数据备份
- 读性能扩展
10.2 配置(一主两从)
- 6379:主
- 6380、6381:从
从库配置:
replicaof 127.0.0.1 6379 masterauth 123456
查看状态:
info replication
11. 哨兵模式(自动故障转移)
11.1 作用
- 监控主节点
- 自动选举新主
- 故障通知
11.2 配置 sentinel.conf
sentinel monitor mymaster 127.0.0.1 6379 1 sentinel auth-pass mymaster 123456 daemonize yes
11.3 启动
redis-sentinel sentinel.conf
12. Redis Cluster 集群部署
12.1 特点
- 无中心
- 16384 个槽分片
- 3主3从企业标准
12.2 集群创建
redis-cli --cluster create 192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005 --cluster-replicas 1
12.3 连接集群
redis-cli -c -p 7000
13. 性能优化与运维规范
13.1 禁止大 Key
- String > 10KB
- Hash/List/Set 元素过多
大 Key 导致:阻塞、迁移慢、内存碎片
13.2 内存优化
maxmemory设置上限- 淘汰策略
allkeys-lru - 开启
activedefrag内存整理
13.3 安全规范
- 必须设置密码
- 禁止外网暴露
- 防火墙限制 IP
- 不要使用默认端口
13.4 监控
- 内存使用率
- 命中率
- 慢查询
- 连接数
- 主从同步状态
14. 总结
本文覆盖 Redis 从零到集群部署 全流程:
- 基础命令 → 数据结构
- SpringBoot 整合 → 序列化
- 事务/锁 → 秒杀实战
- 持久化 → 主从/哨兵/集群
- 缓存问题 → 性能优化


