为了重新设置缓存模式,它在获取和更新数据时定义了以下步骤。
提取项目
更新项目
几乎在所有情况下都能很好地工作,但在一个理论场景中似乎失败了。
如果步骤1& 更新项目中的2个,发生在步骤2和步骤2之间。 3 获取项目。换句话说,考虑到最初数据存储的值为'A'而且它不在缓存中。因此,在获取项目时,我们从数据存储中读取“A”,但在我们放入缓存之前,该项目在另一个线程中更新为“B”(因此'B'已写入数据存储并尝试从缓存中删除该条目,当时不在那里)。现在,当提取线程将其读取的项目(即“A”)放入高速缓存中时。所以现在'A'将保持缓存状态,进一步提取将返回陈旧数据,直到项目过期或再次更新。
所以我在这里遗漏了一些东西,我对模式的理解是错误的。或者说这种情况几乎是不可能的,也没有必要担心它。
此外,我想知道是否可以在模式中进行一些更改以避免此问题。
答案 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."
应修改场景:
提取项目
更新项目
此方案也不能保证完全一致。
想象一下以下情况: 在数据存储中写入项目失败,同时更新缓存中的项目成功。最新的项目值将仅保留在缓存中。