使用数据版本号保证缓存是最新数据


#系统设计


什么是数据版本号?

DB 中的数据,插入时版本号为0,每更新一次,版本号加1。

具体见 数据版本号

什么情况下缓存不是最新数据?

举个例子,有两个线程尝试把同一条数据写入缓存,假设都是先更新DB,再更新缓存,那么当出现下面的情况时,缓存不是最新数据:

  1. 线程1在DB中修改数据
  2. 线程2在DB中修改数据
  3. 线程2更新缓存
  4. 线程1更新缓存

如何保证?

缓存支持数据的版本号,在更新缓存时,新数据的版本号必须大于缓存中已有数据的版本号。

redis 该怎么具体实践?

DB 里要有数据版本号。

redis 本身没有数据版本号的概念,我们可以用将数据版本号存进去。通过 Lua 保证原子性。

例如,我们要存用户 xiaoming 的身高信息,缓存生存时间为 10 分钟。

方式1:lua + 两个 key

一个key是 xiaoming:height,一个 key是xiaoming:height:versionxiaoming:height:version 的缓存生存实践可以大一些,例如 11 分钟。

思路是:

  1. xiaoming:height 不存在,则直接设置xiaoming:heightxiaoming:height:version,流程结束。
  2. xiaoming:height 存在,则查询 xiaoming:height:version,若缓存版本号大于等于要新设置的版本号,则什么都不做,流程结束。
  3. 若缓存版本号小于要新设置的版本号,则设置xiaoming:heightxiaoming:height:version

方式2:lua + 一个 key + 从value 中解析版本号和数据

和方式1类似,不过版本号和数据都存在一个key里面。

方式3:lua + hash 类型

和方式2类似,用 hash 保证数据结构化,hash 中用 data key 存数据,用 version key 存版本号。



( 本文完 )