首次上线场景
1、灰度放量
灰度放量能避免缓存雪崩的问题。假如这个场景中没有放开全量数据,而是只放1%,这样对于系统性能的性能相对较小,后面逐步放量到100%。虽然没有主动同步数据到缓存,但通过控制放量的节奏来保证初始化缓存过程中,不会出现较大耗时波动。如果是新上线的缓存逻辑,可以考虑逐渐灰度放量。
2、扫描数据库刷缓存
- 多模块开发:不仅要写缓存读写逻辑,还要单独开发全表扫描任务(如定时任务、分页查询数据库),相当于做两套功能。
- 并发与限流控制:为了刷的快,要开线程池多线程并行;但又怕刷太快搞垮数据库或缓存,得加限流。
- 异常与边界处理:扫描中如果遇到格式错误、缓存写入失败怎么办?大表扫描时内存溢出怎么避免,这些细节都要逐个解决,代码量和测试量都会增加。
以上,开发成本比较高。
3、数据平台刷缓存
场景:假如是一个电商平台,每天凌晨三点将mysql数据库中的商品库存数据(如商品A有100件库存,商品B有50件)同步到redis缓存,确保用户访问商品页面时能打到缓存,避免数据库压力太大。
- 第一步:mysql数据同步到Hive
mysql是存储业务数据的“在线数据库”(用户下单、运营改库存都实时写Mysql),但直接从Mysql全表扫描刷缓存可能影响线上业务。
Hive:Hive是“离线数据仓库”,专门存储历史数据或批量数据,不直接支撑线上业务,适合做数据处理。数据平台会自动将Mysql中的库存数据复制一份到Hive,相当于给Mysql做备份,后续刷缓存就从Hive取数据,不打扰mysql。
- 第二步:用ETL任务从Hive筛选需要刷缓存的数据
ETL:数据抽取-转换-加载的工具,简单说就是写SQL从Hive中筛选出”需要刷到缓存的数据“,并把结果发送给Kafka。
为什么要ETL:因为不是所有商品都要刷缓存,用ETL可以过滤无效数据,减少缓存写入量。
比如你写了一段Hive SQL,ETL任务会自动执行这段SQL,把筛选出的50万条有效商品库存数据,打包成消息发送到Kafka。
-- 只同步“上架且库存>0”的商品(过滤无效数据) SELECT product_id, stock FROM hive_products WHERE is_online = 1 AND stock > 0
- 第三步:kafka作为”中转站“,控制数据发送速度
kafka:消息队列。ETL任务把50万条库存数据发送到kafka后,它不会一次性把所有数据丢给下游,而是分批、匀速发送,避免下游处理不过来。kafka可以通过”分片“和”消费速率控制“,让缓存写入更加平缓。
- 第四步:消费kafka数据,写入redis缓存
开发一个消费者程序,从kafka中逐条读取商品库存数据,然后写入redis。
为什么不自己控制并发和限流:因为kafka已经帮我们控制了数据发送速度(比如每秒1000条),消费者只需要按这个速度写入redis,无需自己开线程池、加限流代码。
其他场景
除了首次上线,还有什么场景可能需要缓存预热呢?
1、redis挂了
假如redis挂了,全量缓存数据没有了,全部请求同时打到数据库,怎么办?
所以缓存预热还可以用于在缓存挂掉后,重新预热缓存。
2、大量数据冷启动
假如有促销场景,如春节抢红包,平常非活跃用户会在某个时间点大量打开,这也会导致大量cache miss,进而导致缓存雪崩。此时就需要提前预热缓存。
参考
https://zhuanlan.zhihu.com/p/656390288