-
为什么使用缓存?
主要有两个用途:
第一个通过缓存来直接返回数据,不需要再从数据库取出数据(加快读取响应)
第二个支持高并发,在高并发环境下数据库根本撑不住这么多并发量,需要借助缓存实现高并发.
-
缓存分类?
本地缓存: 由于在本机缓存,所以需要注意控制缓存大小,内存泄漏等问题,好处是可以直接在本地读取(更快) ,另外还可以做容灾作用,当我们依赖一个服务的数据时,我们可以将数据缓存在本地,如果服务宕机了,也可以尽可能减少影响.
分布式缓存: 通过数据副本,数据分片,实现大量数据的缓存功能,高可用.
-
缓存的使用
-
先操作数据库,再操作缓存(读操作过程: 读数据先读缓存,读不到的话,再读数据库,然后将读到的数据缓存起来 , 写操作之后讨论)
-
先操作缓存,再操作数据库(借助缓存高效的读写性能,运用于秒杀架构之中)
推荐删除缓存,因为在写数据比较多的场景下,更新完缓存之后,新的缓存没有被读取,可能又需要更新缓存,并且更新缓存代价有时会比较大.
基本没有问题,就是需要考虑删除缓存失败的问题.
结合并发来思考,如果线程A先删除缓存,而线程B因为没有读到缓存,所以去读数据库数据(读到旧数据),而线程A之后更新数据库,但是B线程没有读取到A更新的数据,返回了旧的缓存.此时数据库与缓存就不一致了.
解决1: 将读写请求全放在一个队列里串行执行,但是这样效率会很低.我们可以根据业务hash取模将请求分发到多个队列,同时还可以针对多个连续的读请求来优化,因为连续的读请求会重复读取数据库里的数据,所以我们在读请求入队的时候判断如果它前面也是读请求,那么就不需要入队了,只需要轮询它前一个读请求是否返回缓存,读到缓存就返回.
解决2: 延时双删策略,由于线程B最后会加载旧的数据,所以我们最后可以在更新数据库之后的1s后的旧缓存缓存.
- 将要删除的数据保存起来,保存到数据库(本地事务表),消息队列(Rocket),然后消费者不断重试.
- 订阅bin log日志,然后执行重试删除操作
-
-
缓存雪崩
缓存一时间全部或者大量失效,大量请求进入数据库.分析缓存为什么会失效?
- 缓存发生灾难性故障,这是无法避免,我们通过限流方案保护数据库(放行部分请求,其他请求走降级逻辑),同时在本地缓存部分数据,尽量减少故障的影响.
- 缓存设置了过期时间,大量缓存同时过期,解决方案缓存雪崩,缓存穿透解决方案
Redis缓存使用总结
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.