缓存击穿、缓存穿透、缓存雪崩等并发问题的解决思路

发布时间 2023-09-24 23:38:21作者: ashet

在微服务应用中,每个细微的问题都可能由于并发被无限放大。

并发场景下,比较常见的有:秒杀活动中的商品超卖问题数据冷热分离处理缓存/数据库双写一致性问题缓存击穿缓存穿透缓存雪崩问题等。

在Java基础中,解决并发的思路就是锁,而锁的本质就是将并发执行串行化,在微服务应用中,synchronized关键字、ReentrantLock类提供的各种lock方法均已失效,因为这些锁的作用域是一个服务的单个节点,对其他节点则无法生效。

单机锁不够用了,大佬们就弄了个分布式锁——Redisson/Zookeeper等框架。Redisson选择了AP、Zookeeper选择了CP,因此Redisson性能相对更快,Zookeeper则有效地保证了数据一致性。

用分布式锁,锁住商品id,每个商品则只会被售卖一次,避免商品超卖

用Redis缓存热门数据,并发请求会先去缓存中查询,未查询到再查询数据库,实现数据冷热分离

保证缓存/数据库双写一致性,则是将数据库读+写入缓存这两个操作加上读写锁中的读锁,修改操作加上读写锁中的写锁。读写锁是一种并发控制机制,同时支持读和写操作。在读写锁中,读操作可以并发进行,而写操作会独占锁。读锁也称为共享锁,是一种允许多个线程同时读取数据的锁。

缓存数据的有效时间增加随机偏移量,避免缓存数据同时过期引发缓存击穿带来的数据库压力。

缓存穿透则是频发查询缓存和数据库不存在的数据,这种情况往往伴随着恶意攻击,可以采取Bloom filter 等技术快速判断一些非法请求、增加参数校验、在缓存中设一个空置返回。

缓存雪崩则是Redis扛不住压力的请求量并发访问造成Redis崩溃,进而引起整个系统的大面积功能瘫痪,这种可以采取Redis Cluster集群+Sentinel控流降级应对。