1

我们正在尝试为我们的 Rails 应用程序实现一个高效的 SystemSettings 模块,该模块将基于 Redis。

这应该尽可能快,因为我们几乎在每个请求中都使用 SystemSettings 模块。因此,我们试图将调用此模块产生的开销降至最低。

该模块还将包含一个匹配的 Web UI,用于添加/删除/更新值。

最简单的实现显然是在每个操作上调用 Redis 服务器,但是由于我们的 Redis 服务位于与我们的 Web 服务器不同的服务器中,这显然会为每个操作产生网络开销,这是我们试图避免的事情.

我们正在寻找一种将值缓存一段时间的方法,在此期间,只需返回缓存的结果,而不是调用我们的 Redis 服务。

我们想出的唯一好的解决方案是使用ActionDispatch::Callbacks以确定是否到了更新设置缓存的时间。问题是,对我来说,基于一些随机用户请求来刷新缓存似乎是错误的。

我们还在考虑创建一个每 5 分钟左右运行一次的小脚本,该脚本将调用一个特定的 URL,该 URL 将“触发”一个将启动缓存刷新的操作。这个解决方案的问题在于,这只会导致我们的一个乘客进程(处理请求的进程)的缓存刷新,而不是所有的。

有任何想法吗?

4

1 回答 1

0

问题是,对我来说,基于一些随机用户请求来刷新缓存似乎是错误的。

一点也不。除非您提供请求,否则您不需要清除缓存,因此随机请求与任何请求一样好。请注意,对于任何缓存设置,您都会因本地化数据而牺牲性能,以换取潜在的一致性问题。缓存失效就是这样一个问题。

在你的情况下,我要做的第一件事是真正衡量你是否需要有一个本地化的进程内缓存。Redis 非常快,向它发送多个小请求实际上是该服务器的一个很好的使用模式。您可能会发现网络开销并不是真正的问题。很可能会证明这种开销只是整个响应时间的一小部分(更不用说在浏览器中渲染和资产时间,这会极大地影响用户体验)。

此外,如果你不真正衡量,你怎么知道你改善了情况以及改善了多少?也许 50 行额外代码和增加的复杂性不值得每个请求 20 毫秒的加速?如果没有硬数据,您将无法在这里真正做出明智的决定。

话虽如此,并且假设您确实需要它,我将与缓存读取代码一起实现缓存失效。在写入时存储每个条目的到期时间,在读取时检查时间是否过去。如果是,是时候更新缓存了。

在 Rails 中,您可以使用MemoryStorewithexpires_in选项,例如:

cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
cache.fetch('configuration_key') do
  # your redis contacting code
end
于 2013-03-11T09:53:28.150 回答