gpt4 book ai didi

caching - 缓存失效算法

转载 作者:行者123 更新时间:2023-12-02 12:13:46 25 4
gpt4 key购买 nike

我正在考虑在网络服务器中缓存动态内容。我的目标是通过返回缓存的 HTTP 响应来桥接整个处理,而不影响数据库(或 Hibernate)。这个问题不是关于在现有的缓存解决方案之间进行选择;而是关于如何选择现有的缓存解决方案。我目前担心的是无效。

我确信,基于时间的失效根本没有意义:每当用户更改任何内容时,他们都希望立即看到效果,而不是几秒钟甚至几分钟。而且缓存几分之一秒是没有用的,因为在如此短的时间内不会重复请求相同的数据(因为大多数数据是特定于用户的)。

对于每个数据更改,我都会收到一个事件,并可以使用它根据更改的数据使所有内容无效。由于请求是并发发生的,因此存在两个与时间相关的问题:

  • 失效可能来得太晚,甚至可能会向更改数据的客户端提供过时的数据。
  • 失效完成后,长时间运行的请求可能会结束,其过时数据可能会放入缓存中。

这两个问题有点相反。我想,前者可以通过使用每个客户端的 ReadWriteLock 部分序列化来自同一客户端的请求来轻松解决。所以让我们忘记它吧。

后者更为严重,因为它基本上意味着丢失失效并永远(或太长时间)提供过时的数据。

我可以想象一种解决方案,例如在更改发生之前每个请求开始后重复失效,但这听起来相当复杂且耗时。我想知道是否有任何现有的缓存支持这一点,但我主要感兴趣的是这通常是如何完成的。

澄清

问题是一个简单的竞争条件:

  • 请求 A 执行查询并获取结果
  • 请求 B 进行了一些更改
  • 发生因B导致的失效
  • 请求 A(由于某种原因而延迟)完成
  • 请求 A 的过时响应被写入缓存

最佳答案

要解决竞争条件,请添加时间戳(或计数器),并在设置新的缓存条目时检查此时间戳。这可确保过时的响应不会被缓存。

这是一个伪代码:

//set new cache entry if resourceId is not cached
//or if existing entry is stale
function setCache(resourceId, requestTimestamp, responseData) {
if (cache[resourceId]) {
if (cache[resourceId].timestamp > requestTimestamp) {
//existing entry is newer
return;
} else
if (cache[resourceId].timestamp = requestTimestamp) {
//ensure invalidation
responseData = null;
}
}

cache[resourceId] = {
timestamp: requestTimestamp,
response: responseData
};
}

假设我们收到了对同一资源“foo”的 2 个请求:

  • 请求 A(在 00:00:00.000 收到)执行查询并获取结果
  • 请求 B(于 00:00:00.001 收到)进行了一些更改
  • 由于 B 导致的失效是通过调用 setCache("foo", "00:00:00.001", null)
  • 请求 A 完成
  • 请求 A 调用 setCache("foo", "00:00:00.000", ...) 将过时的响应写入缓存,但由于现有条目较新而失败

这只是基 native 制,还有改进的空间。

关于caching - 缓存失效算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45118929/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com