缓存和数据库数据一致性问题
- 分布式环境下非常容易出现缓存和数据库间数据一致性问题,针对这一点,如果项目对缓存的要求是强一致性的,那么就不要使用缓存。我们只能采取适合的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者之间的强一致性。合适的策略包括:合适的缓存更新策略,更新数据库后及时更新缓存、缓存失败是增加重试机制。
redis雪崩
- 目前电商首页以及热点数据都会去做缓存,一般缓存都是定时任务取刷新,或者查不到之后取更新缓存。定时任务刷新就有一个问题。例如:如果首页所有的数据失效时间都是12个小时,中午12点刷新的,双11零点会有大量用户涌入,假设每秒6000个请求,本来缓存可以抗下每秒5000个请求,但是缓存中所有的key都失效了,此时的6000个/秒的请求全部落在了数据库上,数据库必然扛不住,直接宕机。
redis雪崩应对手段
- 在批量往redis中存数据的时候,把每个key的失效时间加一个随机数,这样就可以保证数据不会在同一个时间过期
- 如果redis是集群部署,将热点数据均匀分布在不同的redis库中也能避免全部失效
- 设置热点数据永不过期,有更新操作就更新缓存(比如更新了首页商品,那刷一下缓存就好了,不需要设置过期时间)
缓存穿透
- 缓存穿透是指缓存和数据库中都没有的数据,而用户(黑客)不断发起请求。例如:我们的数据库id都是从1开始自增的,如果发起id=-1的数据,这样的不断攻击会导致数据库压力特别大,严重会击垮数据库。
缓存击穿
- 缓存击穿和缓存雪崩有一点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿是指一个非常热点的key(大并发集中对这个key进行访问),当这个key失效的瞬间,持续的大并发直接落到了数据库上,就在这个key的点上击穿了缓存。
缓存穿透和缓存击穿的应对手段
- 缓存穿透可以在接口层增加校验,比如:用户鉴权,参数校验,不合法的校验直接return。
- redis内部有一个叫布隆过滤器,这个也能很好预防缓存穿透的发生,它的原理很简单,就是利用高效的数据结构和算法快速判断出你这个key是否在数据库中存在,不存在直接return,存在就去查DB,更新K-V,再return。
- 缓存击穿:设置热点数据永不过去,或者加上互斥锁搞定。