上一篇
凌晨3点,电商团队的小王盯着监控屏幕冷汗直流——某爆款商品页面突然瘫痪,数据库CPU飙到100%,原来这个价值999元的扫地机器人库存只剩最后1件,每秒10万次的查询直接击穿了Redis缓存,所有请求像洪水般涌向数据库...这就是典型的缓存击穿现场!
当某个热点key过期瞬间,海量请求直接穿透缓存砸向数据库(就像子弹击穿防弹衣),与缓存穿透(查询不存在的数据)不同,击穿针对的是真实存在但暂时失效的热点数据。
典型特征:
def get_data(key): data = redis.get(key) if data is None: # 缓存未命中 if redis.setnx("lock:" + key, 1, ex=5): # 加锁 data = db.query(key) # 查数据库 redis.set(key, data, ex=300) # 重建缓存 redis.delete("lock:" + key) # 释放锁 else: time.sleep(0.1) # 短暂等待 return get_data(key) # 重试 return data
优点:实现简单,保证强一致性
缺点:存在死锁风险(需设置锁超时)
// 缓存值结构:{"data":真实数据, "expire":逻辑过期时间} String getDataWithLogicExpire(String key) { String json = redis.get(key); if (json != null) { CacheObj cacheObj = parseJson(json); if (cacheObj.expire > System.currentTimeMillis()) { return cacheObj.data; // 未过期直接返回 } if (redis.setnx("lock:" + key, "1")) { // 获取重建权 new Thread(() -> { String newData = db.query(key); // 异步重建 redis.set(key, new CacheObj(newData, 30*60*1000)); redis.del("lock:" + key); }).start(); } } return cacheObj.data; // 返回旧数据 }
适用场景:允许短期数据不一致的电商类目等
func GetProductDetail(productID string) (string, error) { // 1. 尝试获取缓存 cacheVal, err := redis.Get(ctx, productID).Result() if err != nil && err != redis.Nil { return "", err } // 2. 缓存命中 if cacheVal != "" { return cacheVal, nil } // 3. 获取分布式锁(RedLock算法) lockKey := fmt.Sprintf("lock:%s", productID) mutex := redsync.New(redisPool).NewMutex(lockKey, redsync.WithExpiry(10*time.Second)) if err := mutex.Lock(); err != nil { time.Sleep(50 * time.Millisecond) return GetProductDetail(productID) // 递归重试 } defer mutex.Unlock() // 4. 二次检查(Double Check) cacheVal, _ = redis.Get(ctx, productID).Result() if cacheVal != "" { return cacheVal, nil } // 5. 数据库查询 dbData, err := db.QueryProductDetail(productID) if err != nil { return "", err } // 6. 写入缓存(设置随机过期时间防雪崩) rand.Seed(time.Now().UnixNano()) expire := 300 + rand.Intn(60) // 300~360秒随机 redis.Set(ctx, productID, dbData, time.Duration(expire)*time.Second) return dbData, nil }
技术要点:
开始
│
▼
是否需要强一致性?─────┬─────→ 是 → 使用互斥锁方案
│ (金融交易等场景)
↓ 否
能否接受短暂旧数据?──┬──→ 能 → 逻辑过期方案
│ (商品信息展示)
↓ 不能
使用分布式锁+双重检查
(秒杀/库存等场景)
锁超时陷阱
锁过期时间要大于业务处理时间+网络延迟,否则会出现:
雪崩预防
对热点key采用分级缓存策略:
监控指标
必须配置以下告警:
cache_penetration_count
)lock_wait_duration
)根据2025年Redis官方社区报告,两种新兴方案开始流行:
Tair混合持久化
阿里云推出的「内存+持久化」混合模式,热点key自动持久化,重启后立即恢复
Redis 7.4版原子化操作
新增GETEX
命令组合查询与延期操作:
GETEX key EX 3600 # 查询并自动续期
缓存击穿就像系统血管中的"血栓",而合理的锁机制就是最好的"溶栓剂"。没有万能的银弹,根据你的业务特性(一致性要求、并发量、容忍延迟)选择最适合的方案才是王道,下次遇到流量洪峰时,希望你能淡定地祭出合适的锁方案,让数据库继续"躺平"!
本文由 业梓倩 于2025-07-31发表在【云服务器提供商】,文中图片由(业梓倩)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/498656.html
发表评论