缓存与数据库的一致性思考 https://www.cnblogs.com/johnsblog/p/6426287.html

缓存更新的套路 https://coolshell.cn/articles/17416.html

缓存架构设计细节二三事 http://www.jianshu.com/p/a38b26b55696

缓存方案如何设计才能切合业务需求? https://www.zhihu.com/question/37747712

1、缓存穿透 什么是缓存穿透?

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

2、缓存雪崩 什么是缓存雪崩?

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

ps: 分布式锁的解决并发冲突的方案

  • (1)变更缓存重建以及空缓存请求重建,更新redis之前,都需要先获取对应商品id的分布式锁

  • (2)拿到分布式锁之后,需要根据时间版本去比较一下,如果自己的版本新于redis中的版本,那么就更新,否则就不更新

  • (3)如果拿不到分布式锁,那么就等待,不断轮询等待,直到自己获取到分布式的锁

key的构造规则要讲技巧

eetopin的缓存设计规则

  • 1、遵循 cache aside pattern

  • 2、服务化设计思路 加入一个服务层,向上游提供帅气的数据访问接口,向上游屏蔽底层数据存储的细节,这样业务线不需要关注数据是来自于cache还是DB。

image

  • 3、key的构造规则要讲技巧

    • 医院 HosptialService get update add delete

    • 医生 DoctorService get update add delete

      医生列表 key:key_doctors_{hospital_id} value: array(1,2,3,5,6) or 1,2,3,4,5

      医生获取 key:key_docotor_{docotor_id} value: {doctor_id:1,name:"lunzi"}

    • 会员卡 MemberCardService key:key_member_cards_{user_id} value:array(1,2,3) or 1,2,3

    • 会员卡配置项 MemberCardConfigItemService key:key_card_config_{card_id}
      value: json串 配置的集合

    • 医院、医生、会员卡、会员卡配置项案例分析

  • 4、缓存设计要注意的其它问题

    • 数据库的瓶颈往往在磁盘IO上,所以应该尽量避免对大表的扫描。传统的拆表是按照row去拆分,保持表的体积不会过大,但是缺点是造成应用代码复杂度很高;使用ORM缓存的办法,则是按照column进行拆表,原则一般是:

    • 将大字段拆分出来,放在一个单独的表里面,表只有主键和大字段,外键放在主表当中

    • 将不参与where条件和统计查询的字段拆分出来,放在独立的表中,外键放在主表当中

    • 按照column拆表本质上是一个去关系化的过程。主表只保留参与关系运算的字段,将非关系型的字段剥离到关联表当中,关联表仅允许主键查询,以Key-Value DB的方式来访问。因此这种缓存设计模式本质上是一种SQLDB和NoSQLDB的混合架构设计

    • 以减少数据库服务器磁盘IO为最终目的,而不是减少发送到数据库的SQL条数。实际上使用ORM,会显著增加SQL条数,有时候会成倍增加SQL。

    • 数据库schema设计的取向是尽量设计 细颗粒度 的表,表和表之间用外键关联,颗粒度越细,缓存对象的单位越小,缓存的应用场景越广泛

    • 尽量避免多表关联查询,尽量拆成多个表单独的主键查询,尽量多制造 n + 1 条查询,不要害怕“臭名昭著”的 n + 1 问题,实际上 n + 1 才能有效利用ORM缓存

    • key的互相覆盖问题

    • key的统一管理问题

    • 根据业务场景设计不同业务key的失效期

    • 每个key的缓存时间最好不一致

    • 缓存自动回收策略

    • db结构要设计的合理

    • 按照column拆表实现细粒度对象缓存



www.processon.com