缓存分两类: 数据缓存结果缓存

缓存场景:
  • 数据缓存举例:圈子、帖子、用户、回复。主要应用在单表视图
  • 结果缓存举例:帖子详细(含关联信息)。主要应用在多表业务
缓存时间:
  • 数据缓存缓存时间长。根据实体稳定程度来设置,可以为1天1小时
  • 结果缓存缓存时间短。根据业务关联程度来设置,可以为1小时15分钟
缓存注意:
  • 数据缓存存在实体原子性问题。数据缓存唯一影响他变化的原因就是它自身的改变,不应该依赖其他对象。
  • 结果缓存存在依赖源依赖问题。依赖源的任何改动都会导致缓存无效。常用的做法:一、小时间缓存,间隔失效;二、依赖源改变时主动修改结果缓存。

缓存策略难点:
  • 针对数据缓存,必须明确清楚使用它的结果缓存有哪些,一旦数据缓存改变时,如何同步通知所有关联的结果缓存?(不要小看这点,因为随着共同协作,加之业务量增加,慢慢的设计者可能都不清楚到底我的数据缓存被用到多少个地方,被多少结果缓存引用。)
  • 针对结果缓存,如何在使用时判断它所依赖的关联数据是否改变?
  • 针对程序开发,如何有效的清理指定缓存内容包括它的子依赖数据?

怎么建立一套高效智能的缓存存取更新响应机制? 我们立即来解答 🙂


缓存交互设计

缓存实体:
  • 缓存键:依靠公式生成。生成公式:缓存键 = MD5(信赖键+大写查询条件语句)
  • 缓存值:存储缓存对象。缓存对象可以是数据缓存结果缓存
  • 缓存时间键:表示缓存版本。本键与缓存键一一对应。生成该缓存时,会同时记下缓存依赖键的值(即:依赖键的版本,通常用时间戮),后面用于比对缓存是否需要更新(如果缓存依赖键更新了,则表示当前缓存需要更新)。生成公式:缓存时间键 = 缓存键 + ‘_Time’
  • 缓存时间值:记录依赖键版本。通常为依赖键生成的时间。
  • 依赖键:缓存依赖内容。缓存依赖一旦变化,代表旗下的所有子缓存都失效,需要重新获取。依赖键通常为表名,复杂的依赖键可以自己定义,如“表名+字段名”等。
  • 依赖值:缓存依赖版本。通常为生成依赖键的时间。
  • 注意:上述讲到的内容均为 数据缓存 的设计。

举例1: 帖子结果数据=帖子+圈子+用户+回复,假设帖子结果数据为要缓存的内容,那么帖子、圈子、用户、回复都是帖子结果数据的依赖,它们一旦改变则帖子结果数据就立即失效。但是,千万记住这里的依赖不是依赖键的意思。我们所讲的依赖键只针对单表的设计,不涉及到join。所以,在缓存中应该有数据缓存4个:帖子原表缓存、圈子原表缓存、用户原表缓存、回复原表缓存。然后,再重新组合出帖子结果数据,这时,可以将结果数据作为结果缓存存储。

举例2: 我们现在有两张通用表:一张为通用配置表,一张为通用数据表。通用数据表中有我们能够想到的所有通用字段,字段数量超过30个,而通用配置表则记录每个业务需要用到通用数据中的哪些字段。一个业务一条通用配置记录,对应着多条通用数据记录。到时候一些简单的逻辑,我们就不用建表,直接走通用数据。这个时候,我们会发现如果缓存通用数据,那么依赖键的设置单纯的表名是不够的,要使用表名+配置ID来关联。

缓存案例:

案例背景:请求动画详细信息,信息包括:动画表所有字段、动画分类表名称字段。

  •   动画表名:media_video_tb
  • 动画分类表名:media_video_type_tb

案例设计:为动画表、动画分类表依次建立数据缓存,然后再组合内容成目标动画详细信息

场景模拟:

数据缓存实例:动画表(案例以动画表为例,动画分类表类同)

  • 缓存键:MD5(‘media_video_tb’+’|’+’SELECT * FROM MEDIA_VIDEO_TB’)。
  • 缓存值:[{id:1,name:’宝宝学数字’,type_id:1},{id:2,name:’宝宝懂礼貌’,type_id:2},…]。
  • 缓存时间键:${缓存键} + ‘_Time’
  • 缓存时间值:201701010000(例)
  • 依赖键:media_video_tb
  • 依赖值:201701010000(例)

一、首次获取:

(1)缓存中无依赖。生成依赖键并赋值当前时间戮。

Redis Key Redis Value
media_video_tb 201701010000

(2)缓存中无缓存。生成缓存并同步依赖键值内容。

Redis Key Redis Value
3d2843a3064d296300773e4d320801cc [{id:1},{id:2}]
3d2843a3064d296300773e4d320801cc_Time 201701010000

二、再次获取:

(-)判断本SQL语句对应的缓存时间键与依赖键值是否相同。

  •  相同:则表示未改变,直接获取缓存的值;
  • 不相同(或依赖键不存在)则表示缓存过期,需要重新从数据库拉取。

三、后台更新:

(-)当后台管理进行动画表的增删改操作时,程序代码进行自身依赖键的删除。那么,下一次请求动画表时将会引发缓存过期重新查询数据库。

Redis Key Redis Value
media_video_tb null