实战首选缓存策略,保证 Redis 和 MySQL 的一致性

(这里说的“首选”,是一般而言。根据具体情况,可能有更合适的方案。)

1 关于缓存的共识

想使用缓存,首先要达成以下共识:

  • 缓存必须要有过期时间;
  • 保证数据库跟缓存的最终一致性即可,不必追求强一致性。

尤其是第二点,这是一个 TradeOff。如果非得要求强一致性,就不要用缓存。

本文讨论的策略,只是保证最终一致性。

2 实战首选:旁路缓存策略(Cache-Aside)

进入正题。我在实际工作中,采用的是这个策略的变种。

2.1 读数据

流程:

  1. 当应用程序需要从数据库读取数据时,先检查缓存数据是否命中。
  2. 如果缓存未命中,则查询数据库获取数据,同时将数据写到缓存中,以便后续读取相同数据会命中缓存,最后再把数据返回给调用者。
  3. 如果缓存命中,直接返回。

伪代码:

String cacheKey = "桩白墨";
String cacheValue = redisCache.get(cacheKey);
//缓存命中
if (cacheValue != null) {
  return cacheValue;
} else {
  //缓存缺失, 从数据库获取数据
  cacheValue = getDataFromDB();
  // 将数据写到缓存中
  redisCache.put(cacheValue)
}

2.2 写数据

流程:

  1. 写数据到数据库;
  2. 将缓存中的数据失效或者更新缓存数据;

伪代码:

String cacheKey = "桩白墨";
updateDataInDB(cacheKey, value);
redisCache.deleteKey(cacheKey);

3 首选理由简述

  • 简单有效
  • 高并发场景下,也能保证最终一致性

参考文章:https://juejin.cn/post/7110120022848045092