Redis缓存与MySQL一致性的实现

一、实时同步

对强一致要求比较高的,应采用实时同步方案,即查询缓存查询不到再从DB查询,保存到缓存;更新缓存时,先更新数据库,再将缓存设置过期(建议不要去更新缓存内容,直接设置缓存过期)

@Cacheable:查询时使用,注意Long类型需转换为String类型,否则会抛异常。
@CachePut:更新时使用,使用此注解,一定会从DB上查询数据
@CacheEvict:删除时使用
@Caching:组合用法

二、异步对列

对于并发程度较高的,可采用异步对列的方式同步,可采用kafka等消息中间件处理消息生产和消费。

缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决办法:

持久层查询不到就缓存空结果,查询时先判断缓存中是否exists(key),如果有直接返回空,没有则查询后返回。
注意insert时需清除查询的key,否则即便DB中有值也查不到(当然也可以设置空缓存的过期时间)

缓存雪崩

如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。

解决方法:

这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。
大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。

热点Key

热点key:某个key访问非常频繁,当key失效的时候有大量线程来构建缓存,导致负载增加,系统崩溃。

解决方法:

1、使用锁,单机用synchronized,lock等,分布式用分布式锁。
2、缓存过期时间不设置,而是设置在key对应的value里。如果检测到存的时间超过过期时间则异步更新缓存。
3、在value设置一个比过期时间t0小的过期时间值t1,当t1过期的时候,延长t1并做更新缓存操作。
4、设置标签缓存,标签缓存设置过期时间,标签缓存过期后,需异步的更新实际缓存。

发布了179 篇原创文章 · 获赞 185 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Sophia_0331/article/details/104796763