首页>安全>正文

微博亿级流量下的热点缓存:本地+多副本+自动探测怎么落地

Feng 47 阅读 安全

热点key打穿单个Redis分片,是社交场景里最先爆的地方。一条微博冲上热搜,几秒内请求从几百涨到百万级,读的全是同一个key。微博的解法不是换更强的机器,而是把压力拆到多个维度上:本地缓存挡尖峰,分布式缓存撑容量,中间再加一层自动探测和副本路由。

本地缓存先扛第一波

每个业务机器在JVM内留一份最近访问过的热点数据副本,Caffeine或Guava都能做,TTL压到1到3秒。突发流量进来时,绝大部分读请求直接命中本地,根本走不到Redis。

容量有限不是问题。热点数据的生命周期本来就只有几分钟,短TTL足够覆盖最猛的那段。

本地缓存同时失效,才是真正的坑

所有机器TTL一致的话,同一时刻集体过期,请求会瞬间全部压向Redis,这就是缓存雪崩的雏形。

微博的应对是热点探测组件:持续统计key的访问频率,QPS超过阈值就标记为热点,自动把该key的副本复制到多个Redis实例。客户端读取时,用一致性哈希加一层路由表,随机挑一个副本。单个分片的压力就被摊到多台物理机上。

写操作同步写所有副本,读只读一个。热点数据存活时间短,这种最终一致性可以接受。

预加载和分级,决定内存会不会爆

运营后台能提前判断哪些事件会热,比如电影上映、明星生日,提前把相关数据灌进缓存,避免第一次请求穿透到DB。

但预加载不能什么都塞。微博按热度分级:最热的一级放本地缓存和Redis热点副本,次级热点放普通Redis分片,冷数据走DB加一层薄查询缓存。

这套分层调度让核心API在春晚红包这类极端流量下仍能维持低延迟。

淘汰策略和穿透防护的细节

本地缓存不能简单用LRU。热点是突发的,纯LRU会把刚冒头的数据淘汰掉。微博用访问时间加访问频率做加权评分。

穿透防护靠布隆过滤器,对新创建、还没写入缓存的key先过滤一遍。但布隆过滤器有误判率,所以还要配空值缓存:DB查出来是null,也把这个null缓存一小段时间。

配图

实时发现新热点

靠人工配置跟不上微博的流量变化。内部有一套基于流式计算的实时热度平台,每隔几秒扫描全站请求记录,用滑动窗口找出突增的key,自动触发热点副本创建和本地缓存预热。

全流程自动化,人只在极端异常时介入。

本地缓存一致性:广播失效加去重

A节点更新了数据,B节点还在用旧的,这是本地缓存绕不开的问题。

做法是写操作除了更新Redis,还通过内部RPC广播失效通知,让其他节点立即清本地缓存。热点key数量有限,广播开销可以接受。

为压住广播风暴,设一个去重窗口:同一个key在1秒内只广播一次。

哪些场景别照搬

中小团队直接上Redis集群就以为能扛热点,通常会在吞吐峰值时崩盘。真正的关键是理解热点的局部性和时间性。

但本地缓存吃内存、热点副本吃Redis资源,业务流量不够大的话,很容易过度构建。电商秒杀、高并发社交这类场景可以借鉴,前提是按实际流量精细调优。

验证这套方案是否生效

上线后不能只看平均延迟。用压测工具对单个热点key打高并发读,观察Redis单分片QPS是否被摊平到多个实例。

本地缓存命中率要单独打点,低于预期说明TTL或容量设置有问题。

热点探测的阈值和滑动窗口需要反复调,阈值太高漏报,太低会误判普通key,白白占用副本资源。

一个容易忽略的部署细节

本地缓存和热点副本都依赖应用层配置。如果各节点TTL、路由表版本不一致,会出现部分节点读旧副本的情况。

发布时建议先灰度,确认路由表同步后再全量。

# 查看Redis各分片QPS,确认热点是否被摊平
redis-cli -h <host> -p <port> info stats | grep instantaneous_ops_per_sec

# 查看单个key所在分片
redis-cli -h <host> -p <port> cluster keyslot <key>

判定标准很直接:热点key的请求应分散到多个分片,单分片QPS不出现明显尖峰;本地缓存命中率稳定在高位;DB侧没有因穿透出现突发查询。

Feng
这位作者很神秘,还没有填写简介。