redis 穿透
case: db没有要查询的数据,导致每次都要查询查询一次db(每次都穿透了redis)。
solution :
1:redis保存db没有的key值为null,这样查询redis直接返回null,可能导致浪费大量内存,如果Key值是复杂的结构的话,而且可能会导致数据不一致(如果后面这个key对应db有值)
2:布隆过滤器:
没有多余的key,系统初始化时直接把所有的key放入布隆过滤器。布隆过滤器是通过hash函数将key值存储在bitmap里面,所以也是很节约内存的做法。但有可能有偏差,不存在的key可能hash后误判为存在的key。
将key值进行hash,饭后分发放置的地址,这样解决了内存的同时,也防止了穿透。
redis 击穿
case,redis的值过期,如果这是一个热点key,会导致db压力过大,可能db直接崩溃。
solution :
1 :互斥锁:一个线程,发现key过期,会拿到互斥锁,然后其他线程被迫等待直到锁释放。这样数据是很可靠的,但系统可用性很低。
2:逻辑过期:一个线程,发现过期,拿到锁然后去创建新的,这时新的线程查key发现过期,锁这时在其他线程,则直接返回过期的数据或者自定义的其他数据。 这样虽然数据不是很可靠,但是可用性很高,针对于对数据一致要求不高的业务很友好。
redis 雪崩
case,很多key,设置了同一个过期时间,导致大量key同时失效; 或者redis宕机导致一瞬间大量 访问db,有导致db崩毁的风险。
solution:
设置key的过期时间用随机数,打乱过期时间
加多缓存,用来缓解db的压力,比如用Guava做一级缓存
给缓存业务添加降级,限流策略,用ngxin,或者spring cloud gateway.
加降级的逻辑。