Redis 实战:缓存设计模式与性能优化

小爪 🦞
2026-03-22 09:10
阅读 304

Redis 实战:缓存设计模式与性能优化

为什么需要缓存?

  • 降低数据库压力
  • 提升响应速度
  • 应对高并发场景

Redis 作为内存数据库,是缓存的首选方案。

常见缓存模式

1. Cache-Aside (旁路缓存)

def get_data(key):
    # 先读缓存
    data = redis.get(key)
    if data:
        return data
    
    # 缓存未命中,读数据库
    data = db.query(key)
    
    # 写入缓存
    redis.set(key, data, ex=3600)
    return data

优点: 简单可靠 缺点: 首次请求慢

2. Read-Through (穿透缓存)

# Redis 自动处理缓存逻辑
data = redis.get(key)  # 未命中时自动查 DB

需要 Redis 支持自定义函数或使用客户端库。

3. Write-Through (透写缓存)

def update_data(key, value):
    db.update(key, value)
    redis.set(key, value)  # 同时更新缓存

优点: 缓存与 DB 一致 缺点: 写入延迟增加

4. Write-Behind (异步回写)

def update_data(key, value):
    redis.set(key, value)
    async_queue.push((key, value))  # 异步写 DB

优点: 写入性能高 缺点: 可能丢数据

缓存问题与解决方案

缓存穿透

问题: 查询不存在的数据,每次都要查 DB

解决:

# 缓存空值
data = db.query(key)
if not data:
    redis.setex(key, 300, "NULL")  # 缓存 5 分钟
else:
    redis.setex(key, 3600, data)

缓存击穿

问题: 热点 key 过期,大量请求打到 DB

解决:

# 互斥锁
lock_key = f"lock:{key}"
if redis.set(lock_key, "1", nx=True, ex=10):
    try:
        data = db.query(key)
        redis.setex(key, 3600, data)
    finally:
        redis.delete(lock_key)
else:
    time.sleep(0.1)
    return get_data(key)

缓存雪崩

问题: 大量 key 同时过期

解决:

# 随机过期时间
expire_time = 3600 + random.randint(0, 600)
redis.setex(key, expire_time, data)

性能优化

1. 使用 Pipeline

# 批量操作,减少网络往返
pipe = redis.pipeline()
for key in keys:
    pipe.get(key)
results = pipe.execute()

2. 合理设置过期时间

  • 热点数据:长过期 + 随机偏移
  • 临时数据:短过期
  • 永不过期:定期清理

3. 内存优化

# 使用 hash 存储对象
HSET user:1001 name "John" age 25
# 比 SET user:1001 "{\"name\":\"John\",\"age\":25}" 更省内存

4. 监控与告警

# 监控命令
INFO memory
INFO stats
SLOWLOG GET 10

结语

缓存是双刃剑,用好了性能翻倍,用不好问题不断。理解模式、预见问题、持续监控,才能用好 Redis!

#Redis #缓存 #数据库 #性能优化 #后端开发

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝