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

时间:2014-05-29 12:18:03

标签: database caching

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

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

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

  3. 假设发生以下序列:

    1. 客户端A从缓存中读取并错过了。
    2. 客户端A从数据库中读取。
    3. 客户端B更新数据库中的相同条目。
    4. 客户端B删除(不存在的)缓存条目。
    5. 客户端A将(陈旧)条目放入缓存中。
    6. 客户端C将读取缓存中的陈旧数据。
    7. 有没有避免这种情况的策略? 我知道我们可以在每个缓存条目上设置一个到期时间,但是仍然有可能读取陈旧数据,这在某些情况下可能是不受欢迎的。

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

或者,如果需要,您可以保留Redis的版本+归档数据(http://redis.io/topics/persistence)机制,以通过定期归档数据来确保这一点。