程序中,有许多使用缓存的场景,一个庞大的业务系统,会产生各种各样的缓存方案,数据的一致性成了最头疼的问题。
本文大概介绍一个批量失效缓存的方案。
首先以一个java项目列举一个场景,项目中需要用到大量的查询缓存,
如查询:
客户的订单列表缓存,
客户的基本资料信息缓存,
客户的联系方式缓存
xxxx等等
假如有上十个查询缓存,其中公用到了一个信息:客户的手机号
也就意味着,当客户的手机号变更的时候,这无数个相关联的缓存需要一一失效,这是一件麻烦的并且不便于统一管理的缓存场景。那么这个时候就引出了一个“版本号”的概念,当这一批缓存需要更新的时候,我们讲版本更新,这样所有缓存也会相继更新失效。
什么是版本号呢,版本号只是一个描述,我们可以理解为缓存key中的一个公用串,所有缓存的key中都带有这相同的一串版本号,当我们需要更新批次缓存,将这串版本号更新失效即可,版本号的使用要素是,这批次缓存key中都需要有一个相同维度的关键key成分,如一个客户相关的缓存,那么他的uid就可以座位一个关键key成分,这个uid就可以用来作为版本号的替换key要素。
我们举例几个key:
客户的uid假设为:123

订单列表缓存key:                   "order:cache:list:123"
客户的基本资料信息缓存key: "user:cache:base:123"
客户的联系方式缓存key:        "user:cache:contact:123"

此时可以看到三个缓存key的公用关键要素就是uid。所以缓存中还需要单独存入版本号的缓存。
缓存的key为uid,value可以是当前时间戳: {“123”:“1643352369”}
因此,一个完整的正常的key应当是

订单列表缓存key:                   "order:cache:list:1643352369"
客户的基本资料信息缓存key: "user:cache:base:1643352369"
客户的联系方式缓存key:        "user:cache:contact:1643352369"

当用户资料被修改后,如手机号被修改后,以上批次缓存需要全部更新,那么这时候我们只需要将版本号更新即可
因此,在做客户信息修改的时候,调用更新版本号uid的缓存的value
{“123”:“1643353381”}

以上就是大概的版本号的思路。
实际上每次查询缓存之前,我们需要将原本的uid也就是123的key替换为版本号的value. 因此我们可以每次查询使用的key之前,通过AOP切面的方式,将uid替换为版本号的值。