前言
Redis 是现代互联网应用中不可或缺的缓存和数据存储引擎。在高并发场景下,Redis 通过内存存储和高效的数据结构,提供毫秒级的响应时间。本文将介绍如何在实战中设计和应用 Redis,包括缓存策略、高可用方案和性能优化。
一、Redis 核心特性
1.1 五大数据结构详解
- String:最基础的键值对,支持整数原子操作,适合计数器、分布式锁
- List:有序双向链表,支持头尾操作,适合消息队列、排行榜
- Set:无序集合,支持交并差运算,适合标签系统、粉丝列表
- Sorted Set:有序集合(按分数),适合排行榜、延迟队列
- Hash:哈希表,适合存储对象、减少内存占用
1.2 核心命令详解
-- 字符串操作
SET user:1001:name "Alice" EX 3600
GET user:1001:name
INCR user:1001:login_count
MSET key1 val1 key2 val2
MGET key1 key2
-- 列表操作(消息队列)
LPUSH queue:tasks task1 task2
RPUSH queue:tasks task3
LPOP queue:tasks
LLEN queue:tasks
LRANGE queue:tasks 0 -1
-- 集合操作
SADD tags:article1 python redis database
SMEMBERS tags:article1
SCARD tags:article1
SINTER tags:article1 tags:article2 # 交集
-- 有序集合(排行榜)
ZADD leaderboard 100 player1 95 player2 105 player3
ZRANGE leaderboard 0 -1
ZREVRANGE leaderboard 0 9 # 倒序前10名
ZRANK leaderboard player1 # 获取排名
二、缓存设计模式
2.1 Cache-Aside 模式(旁路缓存)
最常用的缓存模式。应用先查询缓存,缓存未命中则查询数据库,然后写入缓存。
// 伪代码示例
function getUserInfo(userId) {
// 1. 先查缓存
data = redis.get("user:" + userId)
if (data != null) return data
// 2. 缓存未命中,查数据库
data = db.query("SELECT * FROM users WHERE id = ?", userId)
if (data != null) {
// 3. 写入缓存,设置 1 小时过期
redis.setex("user:" + userId, 3600, data)
}
return data
}
2.2 Write-Through 模式(写穿)
写入时同时更新缓存和数据库。保证一致性,但写入速度较慢。
2.3 缓存穿透解决方案
- 空值缓存:对不存在的数据也缓存一个空值,设置较短的过期时间(5分钟)
- 布隆过滤器:用位图判断数据是否存在,可节省内存
- 参数验证:验证请求参数的合法性
2.4 缓存雪崩与击穿
缓存雪崩是指大量缓存同时失效。解决方案:使用随机过期时间、缓存预热。缓存击穿是指热点数据失效导致大量请求打到数据库。解决方案:使用互斥锁或者布隆过滤器。
三、缓存失效与管理
3.1 过期策略
-- 设置过期时间
EXPIRE key 3600 # 设置 1 小时后过期
PEXPIRE key 5000 # 毫秒级过期
SET key value EX 3600 # 设置带过期时间的值
-- 查看和管理 TTL
TTL key # 返回剩余秒数(-1:永久,-2:不存在)
PTTL key # 返回剩余毫秒数
PERSIST key # 移除过期时间
3.2 缓存预热与惰性加载
系统启动时预热热点数据到 Redis,避免冷启动时大量请求打到数据库。同时实现惰性加载机制,当缓存不存在时动态加载。
四、Redis 持久化
4.1 RDB 快照模式
定期创建内存快照,保存为二进制文件。优点:文件小,加载快;缺点:可能丢失最后一次快照以后的数据。
# redis.conf 配置
save 900 1 # 900秒内至少1个键改变则保存
save 300 10 # 300秒内至少10个键改变则保存
save 60 10000 # 60秒内至少10000个键改变则保存
# 手动触发快照
BGSAVE # 后台异步保存
SAVE # 阻塞保存(不推荐)
4.2 AOF 日志模式
记录每条写操作命令。优点:数据安全性高;缺点:文件较大,启动速度慢。建议与 RDB 一起使用。
五、高可用方案
5.1 主从复制
-- 从节点连接主节点
slaveof 192.168.1.100 6379
-- 查看复制状态
INFO replication
5.2 Redis Sentinel(哨兵)
自动监控主从节点,当主节点故障时自动转移。推荐在生产环境中使用。
5.3 Redis Cluster(集群)
将数据分布到多个节点,支持水平扩展和高并发。每个节点负责一部分槽位。
六、性能优化技巧
6.1 使用 Pipeline 减少网络开销
// 单次往返多条命令
redis.pipeline()
.set("key1", "value1")
.set("key2", "value2")
.incr("counter")
.execute()
6.2 连接池配置
使用连接池而不是每次创建新连接。通常配置连接数为 CPU 核心数的 2-3 倍。
6.3 内存优化
- 使用更紧凑的数据结构(如 Hash 代替多个 String)
- 启用压缩(如 ziplist)
- 定期删除过期数据
- 监控内存占用,设置最大内存限制
七、生产环境最佳实践
- 使用 Sentinel 或 Cluster 实现高可用
- 启用 AOF + RDB 双重持久化
- 合理设置过期时间,避免缓存积压
- 使用监控工具(Redis Exporter + Prometheus)
- 定期备份重要数据
- 使用密码和 IP 白名单保护 Redis
总结
Redis 是高性能系统的关键组件。掌握其核心特性、缓存策略和高可用方案,能够构建稳定高效的互联网应用。关键是理解业务需求,选择合适的数据结构和过期策略。