Cache Aside Pattern
- 读的时候,先读缓存,缓存没有再读数据库,读完数据库,放入缓存,同时返回响应。
- 更新的时候,先删除缓存,再更新数据库。
缓存双写不一致
- 先修改数据库,再删除缓存,显然不行,万一删缓存失败则缓存不一致了
- 先删缓存,再更新数据库。能解决低并发下的情况,高并发读时还是会出现缓存不一致。解决方案一:双检分布式读写锁,如果缓存不存在了,加读锁去读取,更新的话,加写锁。方案二:使用队列串行化数据,读请求到达时,先把请求丢到队列里去(其实也是变相加锁),这里可以对读压缩(读锁不互斥)。
缓存多维化
- 一个商品的信息可能有字段,比如描述,颜色,厂家等,如果都集中到一个value里,每次都取出来,然后只修改其中一个属性,再全部写回去,对于 redis消耗不算低,通常是将商品信息按不同维度缓存起来。
分发层+应用层提高缓存命中率
- nginx层为什么命中率低?因为同一个商品请求可能打到不同的nginx上,使得nginx不生效,解决方案就是增加分发层nginx,通过设定规则,将商品的请求路由到指定nginx上。
冷启动(redis没有数据情况下启动)如何保证MySQL不被挂掉(缓存预热)
- 利用storm实时计算,计算出热点数据,并通过ZK存储。然后缓存初始化服务负责从ZK中取出最热数据ID,然后从数据库加载到redis中。
缓存热点问题(超热商品瞬间20W流量到nginx,redis也可能导致崩溃)
- storm实时计算,算出当前最热门的商品,然后将它发给nginx分发层服务器,之后会对它采取降级方案,即将该商品的请求分发给了所有的nginx,这样nginx就扛住了。
缓存雪崩
- 事前尽量保证redis高可用
- 事中保证,ehcache,对redis访问的资源隔离,对源服务访问的限流以及资源隔离。
- 事后如果有备份则快速使用,没有则使用Storm冷启动方案