if not redis.set(f'lock:{key}', 1, nx=True, ex=10):
    time.sleep(0.05)
else:
    data = load_from_db(key)
    redis.set(key, data, ex=600)

爆款商品缓存到期的那几秒,数据库连接数突然打满,接口大面积超时。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:热点键失效瞬间没有兜底,所有请求同时回源重建缓存。

围绕「缓存击穿」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。监控和日志的时间要对上,时区不一致会多绕很大一圈。

临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

处理上按这个顺序:加互斥锁只放一个请求回源;热点数据设置不过期并后台刷新;空结果也做短期缓存。

确认没问题再收工,缓存到期时数据库压力平稳,接口无超时。

作者 9823189