我的番石榴缓存应该在我的应用程序的哪一层?

时间:2015-07-24 16:57:28

标签: java caching

我现在有一个正在运行的Struts应用程序,目前在服务器端有三层:控制器,服务和dao /数据库层。

我目前在我的服务层上有Guava缓存但是我觉得它在错误的地方看到我的一些CacheLoader我使用我的服务来检索数据。所以现在发生的事情是我的“服务有缓存”而我的“缓存有服务”。似乎错了......

这里应该做什么?

2 个答案:

答案 0 :(得分:1)

我认为这个问题值得长期回答。我们来考虑一个Web应用程序。

在应用程序的任何层上或内部放置缓存可能很有用。有利有弊。

DAO /数据库

缓存可能会引入一致性问题。如果对象得到更新,则需要在缓存中使其无效。将这个逻辑集中在DAO中是个好主意。

此外,DAO层接口应该可以很容易地插入缓存:有一些密钥检索的对象。

服务

如果服务在DAO提供的数据之上进行复杂的计算,并且经常访问,则可能需要缓存计算结果。

如果服务确实提供了来自外部服务器的数据,那么缓存它也是个好主意。

控制器

从概念上讲,这可能是更多或不同的事情。所以我退出了使用这个词。

网络层/模板

缓存对于(部分)渲染结果非常有用。

例如,如果您有一个多语言Web应用程序,但只有一种主要请求的语言,则缓存渲染结果而不是中间服务结果更有用。

网络层/请求级别

缓存网络请求的全部内容。

一些讨论

您可以在不同的图层上缓存,但这可能会导致很多问题。如果您在服务层和Web层内缓存,则堆叠缓存。如果您将每个缓存配置为5分钟的到期时间,这意味着在最坏的情况下,值可能会停留10分钟。这是不可取的。

OTOH,我们假设您的业务要求是:"我希望每5分钟重新计算一次产品销售额前10名"。对于在服务中定义了到期的缓存,这是一个完美的用例。但是,您可能需要在堆栈中传播到期时间,如果有缓存"以上"。

让我们考虑一个缓存已呈现的HTML页面或部分并支持5种不同语言的应用程序。缓存可以存储大量冗余内容,但是当应用程序使用来自DAO的缓存对象并一次又一次地呈现内容时,访问时间更快。所以一般来说,在堆栈中缓存更多"更节省内存,更多地缓存堆栈"将改善延迟,降低CPU使用率,但可能需要更多内存。

答案 1 :(得分:0)

文件,数据库,提供/保留数据的外部服务器......它们被视为数据源,应通过数据访问层(通常称为DAO)进行访问。

由于缓存是存储/检索驻留在内存中的数据的另一个地方,因此最好通过属于数据访问层的接口处理数据访问。