软件架构与思考

👉 所有文章
高性能 高性能设计模式
数据库 数据库分库分表指南 MySQL 建表参考 MySQL 初始化数据的一些方案 数据版本号
分布式 ID 分布式 ID 生成方案探讨
缓存 缓存 使用数据版本号保证缓存是最新数据 基于redis的二级缓存
微服务 如何实现远程调用 RPC 协议中的数据签名验签和加解密方案探讨 关于服务间调用循环依赖的一些思考 我所理解的负载均衡 一致性哈希 基于Redis的分布式会话管理系统 如何部署服务 灰度发布 如何区分上游和下游 日志级别
算法与协议 一个可扩展的 MQ 消息设计 Dynamo涉及的算法和协议 写时复制
任务分发 Gearman入门 如何使用redis构建异步任务处理程序
安全 关于对账的一些理解 一个简单可靠的 Dubbo 请求/响应数据签名方案
其他 使用卫语句减少 if else 嵌套

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


什么是数据版本号?

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 存版本号。


( 本文完 )

文章目录