缓存与会话
Redis 缓存与会话存储
学习如何使用 Redis 作为 Web 应用程序的高性能缓存层和会话存储。减轻数据库负载并加快响应速度。
真实业务场景
某电商平台在秒杀期间需处理 50,000 并发用户。产品详情页每次请求都访问数据库,导致响应时间飙升至 3秒以上。应用服务器重启会导致存储在其中的用户会话丢失。通过引入 Redis 作为缓存和会话存储,页面加载降至 50ms 以下,且会话在部署期间保持持久化。
架构图
客户端请求 → Nginx 负载均衡
↓
应用服务器 (Node.js / Spring Boot)
↓ 检查 Redis 缓存
┌─────────────────────────────────┐
│ Redis (缓存 + 会话存储) │
│ ┌───────────┐ ┌──────────────┐ │
│ │ Cache TTL │ │ Session Hash │ │
│ │ product:* │ │ sess:token:* │ │
│ └───────────┘ └──────────────┘ │
└─────────────────────────────────┘
↓ 仅在缓存未命中时
PostgreSQL / MySQL (主数据库)
关键命令解析
性能分析
Redis GET/SET: 延迟约 0.1ms vs 典型 SQL 查询的 5-50ms。缓存读取速度快 100-500 倍。
Redis Hash 中的会话: 字段访问复杂度为 O(1)。支持部分更新,无完整序列化开销。
内存: 典型会话 (500 bytes) × 10万用户 = ~50MB。Redis 单节点即可轻松处理。
吞吐量: 单个 Redis 实例每秒处理 10万+ 操作。集群模式可线性扩展。
常见陷阱
缓存击穿 (Cache Stampede): 当热点 key 过期时,数百个并发请求同时冲击数据库。使用互斥锁 (SET NX) 或错峰 TTL 来防止这种情况。
数据陈旧 (Stale Data): 如果数据库写入未使缓存失效,旁路缓存模式可能会提供过时数据。更新数据库后务必 DEL 缓存 key。
会话体积膨胀: 在会话中存储完整的用户对象会导致内存浪费。保持会话精简——仅存储 ID 和引用。
无持久化配置: 如果 Redis 在未启用 RDB/AOF 的情况下重启,所有会话将丢失。启用持久化或使用带副本的 Redis 集群。
最佳实践
使用一致的键命名: cache:{entity}:{id} 用于缓存,sess:{token} 用于会话。
始终为缓存 key 设置 TTL。无限制的缓存会导致内存耗尽。
实施旁路缓存 (lazy loading) 模式:先读缓存,未命中再填充。
使用 HSET 存储会话而不是 SET + JSON——支持部分字段更新。
为 TTL 值添加抖动(例如 3600 ± 300s)以防止大规模同时过期。
使用 INFO stats 监控缓存命中率。目标是 90% 以上的命中率。
可运行演示
Redis Demo
Click "Step" or "Run All" to execute commands...
▌