缓存模式中陈旧数据的可能性

时间:2016-10-19 08:49:31

标签: caching design-patterns memcached

为了重新设置缓存模式,它在获取和更新数据时定义了以下步骤。

提取项目

  1. 如果在缓存中找到该项目,则从缓存中返回。
  2. 如果未在缓存中找到,请从数据存储中读取。
  3. 将读取的项目放入缓存并返回。
  4. 更新项目

    1. 在数据存储中写入项目。
    2. 从缓存中删除相应的条目。
    3. 几乎在所有情况下都能很好地工作,但在一个理论场景中似乎失败了。

      如果步骤1& 更新项目中的2个,发生在步骤2和步骤2之间。 3 获取项目。换句话说,考虑到最初数据存储的值为'A'而且它不在缓存中。因此,在获取项目时,我们从数据存储中读取“A”,但在我们放入缓存之前,该项目在另一个线程中更新为“B”(因此'B'已写入数据存储并尝试从缓存中删除该条目,当时不在那里)。现在,当提取线程将其读取的项目(即“A”)放入高速缓存中时。所以现在'A'将保持缓存状态,进一步提取将返回陈旧数据,直到项目过期或再次更新。

      所以我在这里遗漏了一些东西,我对模式的理解是错误的。或者说这种情况几乎是不可能的,也没有必要担心它。

      此外,我想知道是否可以在模式中进行一些更改以避免此问题。

2 个答案:

答案 0 :(得分:1)

根据MSDN definition,您对模式的理解似乎完全正确。实际上,它提到了您描述的相同故障情况。

  

此序列中的步骤顺序非常重要。如果在更新缓存之前删除了该项,则在更改数据存储中的项之前,客户端应用程序有一个小窗口可以获取数据(因为在缓存中找不到它),从而导致包含陈旧数据的缓存。

MSDN文章确实指出," 期望缓存数据始终与数据存储中的数据完全一致是不切实际的。"到期和驱逐是提到处理这个问题的两种策略。

旧计算机科学joke就是这样。

  

计算机科学只有两个难题:缓存失效,命名事物和逐个错误。

你偶然发现了第一个问题。

答案 1 :(得分:0)

  

此外,我想知道是否可以在模式中进行一些更改   避免这个问题。

一般来说,没有办法避免这种情况。 Memcached协议引入了一个特殊命令:

"cas" is a check and set operation which means "store this data but
  only if no one else has updated since I last fetched it."

应修改场景:

提取项目

  1. 如果在缓存中找到该项目,则从缓存中返回。
  2. 如果未在缓存中找到,请从数据存储中读取。
  3. 检查并交换缓存中的相应条目并将其返回。
  4. 更新项目

    1. 检查并交换缓存中的相应条目。
    2. 在数据存储中写入项目。
    3. 此方案也不能保证完全一致。

      想象一下以下情况: 在数据存储中写入项目失败,同时更新缓存中的项目成功。最新的项目值将仅保留在缓存中。