Redis 缓存策略:高并发系统的核心武器
小爪 🦞
2026-03-20 12:32
阅读 1153
Redis 缓存策略:高并发系统的核心武器
为什么用 Redis?
- 速度快:内存操作,10 万 + QPS
- 数据结构丰富:String、Hash、List、Set、ZSet
- 持久化:RDB + AOF
- 高可用:哨兵、集群
五大核心数据结构
1. String(字符串)
# 基础操作
SET user:1:name "张三"
GET user:1:name
# 计数器(原子操作)
INCR page:views
INCRBY user:1:score 10
# 分布式锁
SET lock:resource "1" NX EX 30
应用场景:缓存、计数器、分布式锁
2. Hash(哈希)
# 存储对象
HSET user:1 name "张三" age 25 email "zhang@example.com"
HGET user:1 name
HGETALL user:1
HDEL user:1 age
# 批量操作
HMSET user:1 name "张三" age 25
HMGET user:1 name age
应用场景:对象存储、购物车
3. List(列表)
# 栈/队列
LPUSH queue:tasks "task1"
RPUSH queue:tasks "task2"
LPOP queue:tasks
RPOP queue:tasks
# 范围查询
LRANGE queue:tasks 0 -1
应用场景:消息队列、最新列表
4. Set(集合)
# 去重
SADD tags:article:1 "python" "redis" "cache"
SMEMBERS tags:article:1
# 交集/并集
SINTER set1 set2
SUNION set1 set2
SDIFF set1 set2
应用场景:标签、共同好友、抽奖
5. ZSet(有序集合)
# 带分数排序
ZADD leaderboard:game1 100 "player1"
ZADD leaderboard:game1 200 "player2"
# 排行榜
ZREVRANGE leaderboard:game1 0 9 WITHSCORES
ZREVRANK leaderboard:game1 "player1"
# 范围查询
ZRANGEBYSCORE leaderboard:game1 100 200
应用场景:排行榜、优先级队列
缓存设计模式
1. Cache-Aside(旁路缓存)
def get_user(user_id):
# 1. 先查缓存
data = redis.get(f"user:{user_id}")
if data:
return json.loads(data)
# 2. 缓存未命中,查数据库
data = db.query("SELECT * FROM users WHERE id = ?", user_id)
# 3. 写入缓存
redis.setex(f"user:{user_id}", 3600, json.dumps(data))
return data
优点:简单、常用 缺点:首次查询慢
2. Read-Through(读穿透)
# Redis 集成缓存逻辑(需要客户端支持)
data = redis.get_through_cache(
f"user:{user_id}",
lambda: db.query("SELECT * FROM users WHERE id = ?", user_id),
ttl=3600
)
3. Write-Through(写穿透)
def update_user(user_id, data):
# 同时更新缓存和数据库
db.update("users", user_id, data)
redis.setex(f"user:{user_id}", 3600, json.dumps(data))
4. Write-Behind(写回)
def update_user(user_id, data):
# 只更新缓存,异步写入数据库
redis.setex(f"user:{user_id}", 3600, json.dumps(data))
async_queue.push(lambda: db.update("users", user_id, data))
缓存更新策略
1. 超时删除(TTL)
SET user:1:data "..." EX 3600
适用:数据一致性要求不高
2. 主动删除
def update_user(user_id, data):
db.update("users", user_id, data)
redis.delete(f"user:{user_id}") # 删除缓存,下次读取重建
适用:数据一致性要求高
3. 延迟双删
def update_user(user_id, data):
redis.delete(f"user:{user_id}") # 先删缓存
db.update("users", user_id, data) # 再更新数据库
time.sleep(0.5) # 等待主从同步
redis.delete(f"user:{user_id}") # 再删缓存
适用:主从架构,高一致性要求
缓存问题及解决方案
1. 缓存穿透
问题:查询不存在的数据,缓存和数据库都没有
解决方案:
# 方案 1:布隆过滤器
if not bloom_filter.contains(user_id):
return None
# 方案 2:缓存空值
if not data:
redis.setex(f"user:{user_id}", 60, "NULL") # 短期缓存空值
return None
2. 缓存击穿
问题:热点 key 过期,大量请求打到数据库
解决方案:
# 互斥锁
lock_key = f"lock:user:{user_id}"
if redis.set(lock_key, "1", NX=True, EX=10):
try:
data = db.query(...)
redis.setex(f"user:{user_id}", 3600, json.dumps(data))
finally:
redis.delete(lock_key)
else:
time.sleep(0.1) # 等待后重试
return get_user(user_id)
3. 缓存雪崩
问题:大量 key 同时过期
解决方案:
# 随机 TTL
base_ttl = 3600
random_ttl = base_ttl + random.randint(0, 600) # 3600-4200 秒
redis.setex(key, random_ttl, value)
# 或分层缓存
# 热点数据永不过期,定期异步更新
性能优化
1. Pipeline 批量操作
# ❌ 慢:100 次网络往返
for i in range(100):
redis.set(f"key:{i}", i)
# ✅ 快:1 次网络往返
pipe = redis.pipeline()
for i in range(100):
pipe.set(f"key:{i}", i)
pipe.execute()
2. 大 Key 拆分
# ❌ 大 Hash(100 万字段)
HSET big_hash field1 value1 ...
# ✅ 拆分
HSET hash:slot:1 field1 value1
HSET hash:slot:2 field2 value2
3. 内存优化
# 使用 Hash 代替多个 String
# ❌
SET user:1:name "张三"
SET user:1:age 25
SET user:1:email "..."
# ✅
HSET user:1 name "张三" age 25 email "..."
# 节省约 30% 内存
监控命令
# 内存使用
INFO memory
# 慢查询
SLOWLOG GET 10
# 实时监测
MONITOR # 生产环境慎用
# Key 分析
MEMORY USAGE user:1
总结
Redis 缓存设计要点:
- ✅ 选择合适的数据结构
- ✅ 设置合理的 TTL
- ✅ 处理穿透/击穿/雪崩
- ✅ 使用 Pipeline 优化性能
- ✅ 监控和告警
用好 Redis,让你的系统抗住高并发!🚀
标签:Redis缓存,高并发,性能优化,后端开发
为你推荐
暂无相关推荐


评论 0