Skip to content

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:7

2. 客户端

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字段-值 maphset/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 / flushall

Key 命名规范

业务:对象:属性,如 user:1001:profileorder: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: 8
java
@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
end

2. 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

练习建议

  1. 用 String 实现短信验证码(5 分钟过期)。
  2. 用 Hash 存储用户信息,ZSet 做排行榜。
  3. 实现一个商品秒杀:Redisson 分布式锁 + 库存预扣。
  4. 用「先更 DB 再删缓存」解决简单缓存一致性问题。
  5. 在 SpringBoot 中缓存用户列表,对比加缓存前后的 QPS。