02-Redis 基础与高级
对应原始资料:
项目一前置课b/day11-redis基础、高级04-Redis高级
一、Redis 是什么
- 开源的、基于内存的、键值型 NoSQL 数据库。
- 单线程(命令执行)+ IO 多路复用,性能极高(10 万 QPS)。
- 数据类型丰富、支持持久化、可做集群。
二、应用场景
- 缓存(最常见):减轻数据库压力。
- 分布式锁。
- 计数器、排行榜(有序集合)。
- 消息队列(Stream)。
- 会话存储(Session 共享)。
- 限流(令牌桶)。
三、安装与连接
1. Docker 安装(最快)
bash
docker run -d --name redis -p 6379:6379 redis:72. 客户端
bash
redis-cli
> set k v
> get k图形化:Redis Desktop Manager / Another Redis Desktop Manager / RESP。
四、五大基础数据类型
| 类型 | 说明 | 常用命令 |
|---|---|---|
| String | 字符串/数字 | set/get/incr/decr/incrby/mset/mget |
| Hash | 字段-值 map | hset/hget/hgetall/hdel/hincrby |
| List | 有序列表(双向链表) | lpush/rpush/lpop/rpop/lrange/llen/blpop |
| Set | 无序集合 | sadd/srem/smembers/sismember/sinter/sunion |
| ZSet | 有序集合(带分值) | zadd/zrange/zrevrange/zscore/zincrby/zrank |
特殊类型:BitMap(签到)、HyperLogLog(基数统计)、Geo(地理位置)、Stream(消息流)。
五、Key 设计与通用命令
redis
keys * # 列出所有 key(生产禁用,阻塞)
exists k
del k1 k2
expire k 60 # 过期时间(秒)
ttl k # 剩余时间
type k
select 0 # 切换库(0~15)
dbsize
flushdb / flushallKey 命名规范
业务:对象:属性,如 user:1001:profile、order:2024:count。
六、持久化
1. RDB
- 把内存数据快照到磁盘(dump.rdb)。
save 900 1:900 秒内 1 个 key 变化触发。- 恢复快、文件小;可能丢失最后一次快照后的数据。
2. AOF
- 把每条写命令追加到 appendonly.aof。
appendfsync always/everysec(默认,最多丢 1 秒)/no。- 数据更安全;文件大、恢复慢。
3. 混合持久化(4.0+)
RDB + AOF 增量,兼顾速度和安全。
七、Redis 与 SpringBoot 整合
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>yaml
spring:
redis:
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-active: 8java
@Autowired private StringRedisTemplate redis;
redis.opsForValue().set("name", "tom", 60, TimeUnit.SECONDS);
String name = redis.opsForValue().get("name");八、缓存经典问题(重点)
1. 缓存穿透
查询一个不存在的数据,缓存和 DB 都没有,每次都打到 DB。
- 解决:缓存 null 值(短过期)、布隆过滤器、参数校验。
2. 缓存击穿
某个热点 key 突然过期,瞬间大量请求打到 DB。
- 解决:互斥锁(setnx)重建缓存、热点 key 逻辑过期(不真正过期,后台异步更新)、永不过期。
3. 缓存雪崩
大量 key 同时过期 或 Redis 宕机,请求全打到 DB。
- 解决:过期时间加随机值、Redis 集群高可用、限流降级。
4. 缓存一致性(DB 与 Redis)
- Cache Aside:先更 DB,再删缓存(推荐)。
- 延迟双删:删缓存 → 更 DB → 延迟再删缓存。
- 强一致:用消息队列 / Canal 订阅 binlog 同步。
- 终极方案:分布式锁(写时加锁),但牺牲性能。
九、Redis 高级 —— 分布式锁
1. setnx 简单版
redis
SET lock uuid NX PX 30000 # 不存在才设,过期 30s释放锁必须用 Lua 脚本保证「判断 + 删除」原子:
lua
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end2. Redisson(生产推荐)
java
RLock lock = redisson.getLock("orderLock");
lock.tryLock(10, 30, TimeUnit.SECONDS); // 等待 10s,持锁 30s 自动释放
try { /* 业务 */ } finally { lock.unlock(); }- WatchDog:默认 30s 自动续期,避免业务没执行完锁就过期。
- 可重入:基于 Hash 记录重入次数。
- 支持公平锁、读写锁、信号量。
十、Redis 高级 —— 消息队列
1. List(简单)
LPUSH + BRPOP 实现阻塞队列。
2. Stream(5.0+)
支持消费组、ACK,类似 Kafka,可做轻量级 MQ。
十一、集群与高可用
| 方案 | 说明 |
|---|---|
| 主从复制 | 读写分离,一主多从 |
| 哨兵 Sentinel | 监控主节点,自动故障转移 |
| Cluster | 数据分片(16384 槽),去中心化集群 |
十二、性能优化
- 避免大 key(一个 value > 10KB 慢)。
- 避免热 key(可用本地缓存 + 多副本)。
- 禁用
keys *,用scan。 - pipeline 批量提升吞吐。
- 合理设置过期时间,避免内存膨胀。
- bigkey 扫描:
redis-cli --bigkeys。
练习建议
- 用 String 实现短信验证码(5 分钟过期)。
- 用 Hash 存储用户信息,ZSet 做排行榜。
- 实现一个商品秒杀:Redisson 分布式锁 + 库存预扣。
- 用「先更 DB 再删缓存」解决简单缓存一致性问题。
- 在 SpringBoot 中缓存用户列表,对比加缓存前后的 QPS。