一.Redis 和数据库中的数据不一致的情况是如何发生的?
首先我们需要明确数据一致性的情况
- 缓存中有数据,但是缓存的数据值需要和数据库中的值相同
- 缓存中本身没有数据,那么,数据库中的数据就必须是最新值
如果不符合上述情况,那么就出现了数据不一致的情况。
我们可以根据缓存是不是需要处理写请求,我们可以把缓存分为读写缓存和只读缓存
对于读写缓存来说,如果要进行增删改查需要对于缓存中进行,同时还要通过写回方式,同步回数据库中。
对于只读缓存来说,如果有新的数据新增,会直接去写入到数据库之中,而如果有数据删改的话,只需要把只读缓存中的数据标记为无效。这样,应用后续再访问这些增删改查的数据,就会发生缓存缺失,应用再从数据库中把数据读入缓存之中。
对于缓存来说,我们去对数据进行增删,可能会导致数据不一致问题。
二.如何解决数据不一致问题
重试机制
我们可以通过把要新增/修改的值暂时存放在消息队列中,如果应用没有能够成功删除缓存之或者更新数据库的时候,我们可以从消息队列中重新读取这个值,然后再次进行删除/更新。如果成功更新,那么我们从消息队列中删除。
如果在一定的次数重试之后还是没有成功,我们可以向业务层进行报错。
删除缓存值或更新数据库失败而导致数据不一致,你可以使用重试机制确保删除或更新操作成功。
三.缓存雪崩,缓存击穿和缓存穿透
缓存雪崩是指大量的应用请求无法在Redis 缓存中进行处理,大量请求到达数据库层,导致数据库的压力激增。
第一个原因 : 缓存中大量键过期,导致大量请求没有办法得到处理。
解决办法 : 我们可以通过微调过期时间,对于数据的过期时间增加一个较小的随机数,避免大量数据同时过期。
第二个原因: Redis实例突然发生故障,无法处理请求,进而发生缓存雪崩。
解决办法:
我们可以去实现服务熔断或者请求限流机制。
服务熔断,在发生缓存雪崩的时候,我们暂停业务服务对于缓存接口的访问。
请求限流,我们在业务系统的请求入口前端控制每秒进入系统的请求数,避免过多的请求被发送到数据库中。
缓存击穿 : 针对于某个访问非常频繁的热点请求,无法在缓存中处理,访问该数据的大量请求,都直接发送到DB上。
解决办法: 对于访问频繁的热点数据,我们不设置过期时间。
缓存穿透: 数据不在Redis中,也不在数据库中,导致请求在访问缓存的时候,发生缓存缺失,再去访问数据库的时候,数据库中也没有要访问的数据。
解决办法 : 设置布隆过滤器来解决这个问题。