版本号/时间戳校验 (Version/Timestamp Validation) 是一种通过在缓存中存储数据版本信息,并在更新时进行逻辑校验,从而防止旧数据覆盖新数据(乱序写入)的方案。
核心逻辑
该方案不依赖于删除缓存,而是将缓存视为一个带版本控制的存储。
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1. 读 | 获取数据 + 版本号 | 从数据库读取数据时,带上其版本号 (Version) 或更新时间戳 |
| 2. 写 | 带有条件的写入缓存 | 使用 Redis 的 Lua 脚本,仅当 新版本号 > 缓存当前版本号 时才执行更新 |
| 3. 存 | 存储结构变化 | 缓存内容从 value 变为 { "data": value, "v": version } |
sequenceDiagram participant App1 as 请求 A (旧) participant App2 as 请求 B (新) participant Redis as 缓存 (Redis) Note over App1, App2: 假设数据库中数据已从 V1 更新到 V2 App2->>Redis: 1. 写入 V2 数据 (v=2) Redis->>Redis: 校验成功 (2 > 0) App1->>Redis: 2. 延迟到达的 V1 数据 (v=1) Redis->>Redis: 校验失败 (1 < 2),拒绝写入 Note over Redis: 缓存保持为最新的 V2
痛点与对策
| 挑战 | 技术对策 |
|---|---|
| 存储开销 | 每个 Key 都需要额外存储版本信息,需权衡内存占用 |
| 逻辑复杂度 | 读写逻辑需封装 Lua 脚本,保证版本比对的原子性 |
| 时钟回拨 | 若使用时间戳,需注意服务器时钟同步问题(建议使用数据库自增版本号) |