处理内存缓存中的陈旧数据

Mav*_*ave 6 database caching

假设在数据库前使用内存缓存(例如redis/memcache)的策略是:

  1. 阅读:客户端将首先尝试从缓存中读取.在缓存未命中时,从数据库读取并将数据放入缓存中.

  2. 写入:首先更新数据库,然后删除缓存条目.

假设发生以下序列:

  1. 客户端A从缓存中读取并得到遗漏.
  2. 客户端A从数据库中读取.
  3. 客户端B更新数据库中的相同条目.
  4. 客户端B删除(不存在的)高速缓存条目.
  5. 客户端A将(陈旧)条目放入缓存中.
  6. 然后,客户端C将读取缓存中的陈旧数据.

是否有任何避免这种情况的策略?我知道我们可以在每个缓存条目上放置一个到期时间,但是仍然有可能读取陈旧数据,这在某些情况下可能是不合需要的.

usr*_*usr 5

您可以对缓存数据进行版本控制并保持每个版本不可变。每次数据库中的数据发生更改时,都会增加一个整数版本列。缓存键必须包含版本号。然后,客户端可以首先查看数据库以查找当前版本号,然后与缓存对话。

保持缓存一致非常困难,因为它们是非事务性操作的。没有通用的方法可以防止您所讨论的此类问题。理想情况下,您希望以原子方式使写入在数据库和缓存中可见,但这仅在特殊情况下才有可能。就像我提出的方案一样。

  • @usr如果每次都查询数据库以获得缓存密钥,那么缓存层仍然有用吗? (4认同)