我经常听到人们有性能问题x,他们通过缓存解决了这个问题.
或者,如何在程序代码中执行x,y,z会损害您的缓存能力.
即使在最新的一个播客中,杰夫阿特伍德也谈到了他们如何缓存某些价值以便快速检索.
"缓存"和"缓存"这两个术语似乎有些含糊不清,这让我对它在不同情况下的含义感到困惑.无论您是指应用程序还是数据库缓存,cpu等,这意味着什么.
什么是缓存以及有哪些不同的类型?
从上下文中我可以了解它,将经常检索的值存储到主存中并快速查看它.但是,它真的是什么 ?
这个词似乎用于许多不同的语境(cpu,数据库,应用程序等),我真的很想清除它.
缓存在应用程序中的工作方式与数据库缓存之间有区别吗?
当有人说他们发现了一段会损害缓存的代码并且修复后,它会提高应用程序的速度,他们在谈论什么?
程序的缓存是自动完成的吗?如何允许在程序中缓存值?我经常读到这个网站上的用户说他们在应用程序中缓存了一个值,我坐在这里想知道他们的意思.
此外,当有人谈论数据库缓存时,它真正意味着什么?这只是他们在数据库中打开的功能吗?您是否必须显式缓存值,或者数据库是否选择要为您缓存哪些值?
我如何开始自己缓存项目以提高性能?
你能举几个例子说明我如何开始在我的应用程序中缓存值吗?或者,这是否已经完成,在引擎盖下,我只需要以特定的方式编写我的代码以允许"缓存"?
那么数据库缓存呢,我该如何开始呢?我听说过像memcache这样的东西.这种类型的实用程序是否需要在数据库中缓存?
我希望能够很好地区分应用程序与数据库中的缓存,如何使用它们以及如何在两种情况下实现它们.
缓存只是在高性能存储(通常是内存)中显式或隐式地存储数据和从中检索数据的做法.
让我解释.内存比文件,远程URL(通常),数据库或您喜欢的任何其他外部信息存储更快.因此,如果使用其中一个外部资源的行为很重要,那么您可以从缓存中受益以提高性能.
Knuth曾经说过早优化是万恶之源.那么,就我而言,过早缓存是所有头痛的根源.直到你不解决问题有一个问题.您做出的每一个决定都是以现在支付的成本为代价而再次付费以便稍后进行更改,这样您就可以更长时间地进行扭转并更好地改变您的系统.
因此,首先要确定您确实存在问题以及问题所在.分析,日志记录和其他形式的性能测试将在这里为您提供帮助.我不能强调这一步的重要性.我看到人们"优化"不是问题的东西的次数是惊人的.
好的,所以你遇到了性能问题.假设您的页面正在运行需要很长时间的查询.如果它是一个读取,那么你有很多选择:
将查询作为单独的进程运行,并将结果放入缓存中.所有页面都只是访问缓存.您可以根据需要经常更新缓存版本(每天一次,每周一次,每5秒一次,适当的时候);
通过持久性提供程序,ORM或其他任何内容透明地缓存.当然,这取决于您使用的技术.例如,Hibernate和Ibatis支持查询结果缓存;
如果结果不在缓存中(或者它是"陈旧的",意味着它的计算时间比指定的"年龄"更长),并且将其放入缓存中,请让您的页面运行查询.如果两个(或更多)单独的进程都决定需要更新结果,那么这会产生并发问题,因此您最终会一次运行相同(昂贵)的查询八次.您可以处理此锁定缓存,但这会产生另一个性能问题.您还可以使用您的语言(例如Java 5并发API)回退到并发方法.
如果是更新(或发生需要反映在读取缓存中的更新),那么它会有点复杂,因为在缓存中使用旧值并在数据库中使用较新的值以便随后提供页面并不好对数据的看法不一致.但从广义上讲,有四种方法:
更新缓存,然后排队请求以更新相关商店;
通过缓存写入:缓存提供程序可以提供一种机制来持久更新并阻止调用者,直到进行更改为止; 和
后写式缓存:与直写式缓存相同,但它不会阻止调用者.更新是异步和单独发生的; 和
持久性即服务模型:这假设您的缓存机制支持某种可观察性(即缓存事件侦听器).基本上一个完全独立的进程 - 调用者不知道 - 监听缓存更新并在必要时保留它们.
您选择的上述哪种方法将在很大程度上取决于您的要求,您正在使用的技术以及许多其他因素(例如,是否需要群集和故障转移支持?).
很难比这更具体的,给你做什么指导不知道太多关于您的问题更详细的(像你是否有问题).
您很可能会在Web应用程序的上下文中阅读有关缓存的内容.由于Web的性质,缓存可以产生很大的性能差异.
考虑以下:
网页请求到达Web服务器,Web服务器将请求传递给应用程序服务器,应用程序服务器执行呈现页面的一些代码,该代码需要转向数据库以动态检索数据.
此模型无法很好地扩展,因为随着页面请求数量的增加,服务器必须对每个请求反复执行相同的操作.
如果Web服务器,应用程序服务器和数据库位于不同的硬件上并通过网络相互通信,这就变得更加严重.
如果您有大量用户访问此页面,那么对于每个请求都不会一直进入数据库是有意义的.相反,您可以使用不同级别的缓存.
结果集缓存
结果集缓存是将数据库查询的结果与查询一起存储在应用程序中.每次网页生成查询时,应用程序都会检查结果是否已经缓存,如果是,则将其从内存数据集中拉出来.应用程序仍然必须呈现页面.
组件缓存
网页由不同的组件组成 - 小页面,或者您可能想要调用它们的任何内容.组件缓存策略必须知道用于请求组件的参数.例如,网站上的一个小"最新消息"栏使用用户的地理位置或偏好来显示本地新闻.因此,如果缓存了位置的新闻,则不需要呈现该组件并且可以从缓存中提取该组件.
页面缓存
缓存整个页面的一种策略是将查询字符串和/或标题参数与完全渲染的HTML一起存储.文件系统足够快 - 对于Web服务器来说,读取文件的成本仍然低于调用应用程序服务器来呈现页面的成本.在这种情况下,发送相同查询字符串的每个用户都将获得相同的缓存内容.
智能地组合这些缓存策略是为大量并发用户创建真正可伸缩的Web应用程序的唯一方法.您可以很容易地看到,这里的潜在风险是,如果缓存中的一段内容无法通过其密钥唯一标识,则人们将开始看到错误的内容.这可能变得非常复杂,特别是当用户有会话并且存在安全上下文时.
我知道有两个含义.
一个是应用程序缓存.这是当数据来自某个地方(例如来自网络)的速度很慢或计算速度慢时,应用程序会缓存数据的副本(这样它就不需要再次获取或重新计算:它是已缓存).实现缓存需要一些额外的应用程序软件(使用缓存的逻辑)和额外的内存(用于存储缓存的数据).
你在这里引用的是"缓存":
从上下文中我可以了解它,将经常检索的值存储到主存中并快速查看它.
另一个是CPU缓存,这篇维基百科文章对此进行了描述.CPU缓存自动发生.如果从少量内存中读取大量内容,则CPU可以从其缓存中执行大部分读取操作.OTOH如果你从大量的内存中读取,它不能全部适合缓存,CPU必须花更多的时间来处理较慢的内存.
你在这里引用的是"缓存":
当有人说他们发现了一段会损害缓存的代码并且修复后,它会提高应用程序的速度,他们在谈论什么?
这意味着他们找到了一种重新排列代码的方法,以减少缓存未命中.
至于数据库缓存,我不知道.