首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现web应用程序的缓存

如何实现web应用程序的缓存
EN

Stack Overflow用户
提问于 2011-03-06 03:59:37
回答 2查看 21.4K关注 0票数 7

使用Java和NoSQL数据库开发的web应用程序数据缓存有哪些不同的方法?数据库也提供缓存,它们是唯一的也总是最好的缓存选择吗?

否则,我如何在应用程序上缓存我的用户数据。应用程序包含非常特定于用户的数据,就像在社交网络中一样。有没有一些简单的经验法则来说明应该缓存什么类型的东西?

我还可以使用Java在应用程序服务器上缓存我的数据吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-06 05:02:03

我假设您正在构建一个相对典型的web应用程序:

  1. 只有一台服务器用于持久性
  2. 多个web服务器
  3. 通过负载平衡器

通过粘性会话将经过身份验证的用户连接到单个服务器

现在,就这样回答你的问题吧。大多数持久化,数据库或NoSQL,可能有某种类型的缓存,以便如果您重复执行相同的简单查询(例如,通过主键检索),它能够缓存结果。但是,查询越复杂,持久化就越不可能对其执行缓存。此外,如果只有一台服务器用于持久化(即没有分片或写主/读从),那么它很快就会成为瓶颈。因此,您想要执行的应用程序级缓存通常应该发生在web服务器上,以减少数据库的负载。

就应该缓存的内容而言,启发式是频繁访问和/或生成昂贵的项目(就数据库/web服务器处理/内存而言)。典型的候选者是网站的主页和任何其他登录页面-通常最好的方法是生成一个静态文件并提供服务。接下来的部分取决于您的应用程序,但通常最有效的策略是缓存尽可能接近最终结果-通常是所提供的HTML。对于你的社交网络来说,这可能是一个特色更新的列表或类似的东西。

就用户会话而言,它们绝对是缓存的一个很好的候选。在这种情况下,您可能可以从合理使用web服务器的会话范围(假设是JSP服务器)中获得很多好处。这些数据驻留在内存中,是保存用户在每个页面上进行身份验证时显示的用户特定信息(例如,名字和姓氏)的好地方。

现在要考虑的最后一件事是处理缓存无效,这实际上是所有这些(naming stuff is the other hard thing in computer science)中最难的部分。在这种情况下,使用其他人提到的memcached或ehcache之类的东西是正确的方法。ehcache可以很容易地在您的java应用程序的进程中运行,并且可以很好地执行过期操作,使用最近最少使用和最不频繁使用的策略,并允许您同时使用内存和磁盘进行缓存。您需要考虑的情况是,由于数据已更改,您需要提前终止缓存中的某些内容。在这种情况下,您需要处理应用程序体系结构中的这些依赖项,以便适当地对缓存进行读/写操作。

票数 10
EN

Stack Overflow用户

发布于 2011-03-06 06:00:37

如果你想要一个经验法则,下面是迈克尔·杰克逊(不是迈克尔·杰克逊)说的话:

  1. 程序优化的第一条规则: do‘t do it.
  2. The程序优化的第二条规则(仅限专家!):do’t do it yet.

古老的传统是,你不会优化,直到你分析了--也就是说,直到你有确凿的证据表明什么真正需要优化。缓存是一种优化;它很可能对你的应用程序很重要,但在你能够加载你的应用程序并查看哪些对象需要很长时间才能获得(从数据库加载)之前,你不会知道什么需要缓存。无论你有多聪明,或者你在这里得到了什么建议,在你这样做之前,你的不会知道需要缓存什么。

至于你可以缓存的东西,它是任何东西,但我想你可以把它分成三组:

  1. 来自数据库的最新内容。这些内容很容易缓存,因为在您访问数据库时,您就拥有了缓存键所需的标识信息(主键、查询参数等)。通过缓存它们,您可以节省从数据库中获取它们所花费的时间-这涉及IO,因此它很可能是通过在域模型(可能是社交应用程序中的新闻提要)中计算而产生的large.
  2. Things。这些可能更难缓存,因为生成它们需要更多上下文信息;您可能必须重构代码以创建一个单点,在该点上所有需要的信息都在手边,这样您就可以对其应用缓存。或者你可能会发现它已经存在了。缓存这些将节省所有数据库访问所需的信息,以及所有的计算;计算所用的时间可能会显著增加IO的时间,也可能不会。使这类缓存的内容无效可能比发送到浏览器的纯数据库objects.
  3. Things -页面或页面片段要难得多。这些内容很容易缓存,因为在设计得当的应用程序中,它们由URL或URL和用户的组合唯一标识。缓存这些将节省应用程序中的所有计算;它甚至可以避免为请求提供服务,因为它可以由应用程序服务器前面的reverse proxy完成。有两个问题。首先,它使用了大量的内存:由几千字节的对象呈现的页面可能有几十或几百千字节的大小(我的Facebook主页是50 kB)。这意味着您必须节省大量的计算,使其比在数据库或域模型层缓存更好,而且在设计合理的应用程序中,域模型和HTML之间没有那么多的计算。其次,无效比在域模型中更难,而且很可能经常发生-任何更改页面或片段的操作都需要使缓存无效。

最后,实际的机制:从一些简单的和正在处理的东西开始,比如一个大小有限的map和最近最少使用的驱逐策略。这很简单,但很有效。像EHCache这样的进程外缓存比较复杂,但有两个优点:可以在多个进程之间共享缓存(如果有集群,这很有用,有时可能会这样),还可以将数据存储在垃圾收集器看不到的地方,这可能会节省一些CPU时间(可能--这个主题太大了,不适合在这里讨论)。

但我重申我的第一点:在知道需要缓存的内容之前不要缓存,一旦知道需要缓存什么,就要注意缓存的好处受到的限制,并尽量保持缓存策略的简单性(当然不能更简单)。

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5206421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档