Redis缓存使用总结

  • 为什么使用缓存?

    主要有两个用途:

    第一个通过缓存来直接返回数据,不需要再从数据库取出数据(加快读取响应)

    第二个支持高并发,在高并发环境下数据库根本撑不住这么多并发量,需要借助缓存实现高并发.

  • 缓存分类?

    本地缓存: 由于在本机缓存,所以需要注意控制缓存大小,内存泄漏等问题,好处是可以直接在本地读取(更快) ,另外还可以做容灾作用,当我们依赖一个服务的数据时,我们可以将数据缓存在本地,如果服务宕机了,也可以尽可能减少影响.

    分布式缓存: 通过数据副本,数据分片,实现大量数据的缓存功能,高可用.

  • 缓存的使用

    1. 先操作数据库,再操作缓存(读操作过程: 读数据先读缓存,读不到的话,再读数据库,然后将读到的数据缓存起来 , 写操作之后讨论)

    2. 先操作缓存,再操作数据库(借助缓存高效的读写性能,运用于秒杀架构之中)

    • 缓存的使用-写操作一致性

    • 删除缓存 OR 更新缓存

    推荐删除缓存,因为在写数据比较多的场景下,更新完缓存之后,新的缓存没有被读取,可能又需要更新缓存,并且更新缓存代价有时会比较大.

    • 先更新数据库,再删除缓存

    基本没有问题,就是需要考虑删除缓存失败的问题.

    • 先删除缓存,再更新数据库

    结合并发来思考,如果线程A先删除缓存,而线程B因为没有读到缓存,所以去读数据库数据(读到旧数据),而线程A之后更新数据库,但是B线程没有读取到A更新的数据,返回了旧的缓存.此时数据库与缓存就不一致了.

    解决1: 将读写请求全放在一个队列里串行执行,但是这样效率会很低.我们可以根据业务hash取模将请求分发到多个队列,同时还可以针对多个连续的读请求来优化,因为连续的读请求会重复读取数据库里的数据,所以我们在读请求入队的时候判断如果它前面也是读请求,那么就不需要入队了,只需要轮询它前一个读请求是否返回缓存,读到缓存就返回.

    解决2: 延时双删策略,由于线程B最后会加载旧的数据,所以我们最后可以在更新数据库之后的1s后的旧缓存缓存.

    • 删除缓存失败

    1. 将要删除的数据保存起来,保存到数据库(本地事务表),消息队列(Rocket),然后消费者不断重试.
    2. 订阅bin log日志,然后执行重试删除操作
  • 缓存雪崩

    缓存一时间全部或者大量失效,大量请求进入数据库.分析缓存为什么会失效?

    1. 缓存发生灾难性故障,这是无法避免,我们通过限流方案保护数据库(放行部分请求,其他请求走降级逻辑),同时在本地缓存部分数据,尽量减少故障的影响.
    2. 缓存设置了过期时间,大量缓存同时过期,解决方案缓存雪崩,缓存穿透解决方案
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章