通过每 10 秒查询一次来缓存结果是一个坏主意吗?

7wp*_*7wp 2 asp.net caching

我们有一种情况,我们在 API 上调用一个相当昂贵的函数。让我们称之为API.ExpensiveCall()

ExpensiveCall()在 Web 应用程序中经常被调用。虽然对于一个用户来说并不明显,但当您有 5 个左右的用户同时使用时,它会变得明显。

我们想缓存这些结果。但由于API.ExpensiveCall()对我们来说本质上是一个黑匣子,我们无法使缓存无效,知道何时刷新。

所以我们提出的解决方案是创建一个 Windows 服务,它会简单地API.ExpensiveCall()每十秒调用一次,然后将结果保存到 Web 应用程序已经在使用的本地数据库中。

这样无论网站上有 1 个用户还是 20+ 个用户都没有关系,ExpensiveCall()每 10 秒只调用一次。它是API.ExpensiveCall()所连接的外部系统上非常受控制的负载。

问题

我们的项目经理不同意这一点。出于某种原因,他认为每 10 秒定时刷新是一个坏主意,因为在他看来,这会给外部系统带来太多负载。

但是,如果我们对此不采取任何措施,并且保持原样而不进行任何缓存,则不仅会降低 Web 应用程序的性能,而且肯定会在外部造成每秒超过 1 次的 ExpensiveCall系统。这个数字会随着 Web 应用程序上的用户数量成倍增加。

我想问你这种缓存方式真的很糟糕吗?您是否听说过其他系统使用这种缓存方法?如果这是一个坏主意,当系统对您来说是一个黑匣子时,是否有其他更好的方法来缓存系统的结果?

编辑:

您的回复似乎表明我应该使用 ASP.Net 的内存缓存机制的超时功能。

我喜欢超时的想法。我现在看到的唯一(小)问题是,当超时到期并且是时候调用 ExpensiveCall() 时,它将成为阻塞调用。与查询本地表相反,本地表通过在单独的进程中不断刷新来保持最新。这是我觉得投票想法很有吸引力的地方。尽管我必须承认每 10 秒进行一次轮询确实感觉很奇怪,这就是为什么我对此持观望态度。

tda*_*ers 5

您的项目经理可能是对的:当连续五分钟没有请求时,您仍然会进行轮询,从而导致对昂贵函数的 30 次不必要的调用。

通常解决这些事情的方法是这样的:每当您需要来自昂贵调用的数据时,您就检查缓存。如果它不存在,则调用昂贵的函数并将数据存储在缓存中,并添加时间戳。如果是,那么您检查数据的年龄(因此是时间戳)。如果它早于 10 秒,无论如何都要调用昂贵的函数,并更新您的缓存。否则,使用缓存的数据。ASP.NET 的内置缓存 API 可让您以相当小的工作量完成所有这些工作 - 只需将缓存过期时间设置为 10 秒,您应该就可以了。

这样,您将获得两全其美 - 您的数据永远不会超过 10 秒,但您仍然可以避免持续轮询。