2

我试图了解在允许查询和更新客户注册表数据库的 REST API 层的情况下哪个是最佳缓存策略。我们目前有 3 个前端服务器,它们都与一个中央数据库服务器通信。

这个想法是向调用客户端返回一个 etag,该 etag 与客户记录版本 id 匹配(一个在帐户的任何更改时更新的哈希值),仅当接收到的 etag 与存储的版本 id 匹配时才接受更新调用数据库。

假设客户端对负载均衡器路由到服务器 1 的客户记录执行 GET。服务器 1 没有缓存客户记录,因此将查询数据库,在本地缓存记录并将记录作为包含 etag 标头的调用响应返回。

如果第二个客户端到达并为路由到服务器 2 的相同客户记录执行相同的 GET,则服务器 2 还将在本地缓存条目并返回相同的 etag 标头。

假设现在第一个客户端已经通过服务器 1 对同一记录执行了更新调用。服务器 1 缓存使用最新的记录详细信息进行更新,并且第一个客户端返回一个新的 etag。

在此之后,第二个客户端执行一个有条件的 get 调用,提供带有接收到的 etag 的“If-None-Match”标头集。该请求将再次命中服务器 2。我的假设是服务器 2 仍将缓存旧的 etag,并将向客户端返回 304 Not Modified 响应。这是一个正确的假设吗?

在这种情况下,客户端很容易获得过时的数据,并会影响在客户端看到和使用的数据的整体一致性。

需要什么来解决这个问题并确保任何时候都不会将过时的客户记录数据返回给客户?

非常感谢!

4

3 回答 3

3

缓存失效是一个很难解决的问题。我见过至少有 3 种方法可以解决这个问题。它们因复杂性和过期记录仍被视为有效的时间而异。

  1. 最简单的答案是所有前端服务器都必须调用数据库来验证etag,然后才能返回“304 Not Modified”。如果有很多更新或从数据库下载记录的成本很高,这可能是最好的。

  2. 如果有时可以发回旧值,那么您可以在缓存项目上设置过期时间。

  3. 另一种选择是,当 1 台前端服务器看到更新时,它需要告诉其他前端服务器使该缓存项过期(可能通过调用 Web 服务?)。这允许较长的缓存持续时间,但如果有很多更新,可能会太啰嗦。

于 2013-11-12T23:44:33.953 回答
1

+@David 列表的另一个解决方案:

  1. 使用集中式缓存。它应该可以解决您的问题。尽管它不如本地缓存有效,但在大多数情况下它仍然比查询数据库更快。

可能的集群缓存实现有:couchbaseredis cluster。最流行的非集群实现是memcached

于 2013-11-14T00:43:50.650 回答
0

正如谷歌发布的这篇文章,您可以使用分层缓存来解决某些情况下的缓存无效问题,特别是对于静态资产。

基于其指纹(附加)命名资产并使顶层不可缓存是这里的基本思想。

于 2017-11-30T06:49:40.897 回答