何时/在 Rails 3 中缓存什么

发布于 2024-12-10 19:49:55 字数 297 浏览 1 评论 0原文

缓存是我很长一段时间都忽略的事情,因为我从事的项目位于本地 Intranet 上,活动很少。我现在正在开发一个更大的 Rails 3 个人项目,我正在尝试弄清楚应该缓存什么以及何时缓存。

  1. 人们一般如何判断这一点?
  2. 如果我知道某个网站的活动量相对较低,我是否应该缓存每个页面?
  3. 如果我有一个调用多个部分的页面,那么在这些部分中进行片段缓存或在这些部分上进行页面缓存更好吗?

Ruby on Rails 指南很好地解释了 Rails 3 中的缓存如何工作,但我无法理解与之相关的决策过程。

Caching is something that I kind of ignored for a long time, as projects that I worked on were on local intranets with very little activity. I'm working on a much larger Rails 3 personal project now, and I'm trying to work out what and when I should cache things.

  1. How do people generally determine this?
  2. If I know a site is going to be relatively low-activity, should I just cache every single page?
  3. If I have a page that calls several partials, is it better to do fragment caching in those partials, or page caching on those partials?

The Ruby on Rails guides did a fine job of explaining how caching in Rails 3 works, but I'm having trouble understanding the decision-making process associated with it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还在原地等你 2024-12-17 19:49:56

永远不要为了缓存而缓存,因为有需要而缓存(除了像主页这样的东西,你知道它会非常受欢迎。)启动网站,然后解析你的日志或使用类似的东西NewRelic 查看速度慢的原因。从那里,您可以计算出哪些内容值得缓存。

一般来说,如果某件事需要 500 毫秒才能完成,您应该缓存,如果超过 1 秒,则您可能在请求中执行了太多操作,并且您应该将正在执行的任何操作转移到后台进程......例如,获取Twitter 提要,或处理图像。

编辑: 也请参阅 apneadiving 的答案< /a>,他链接到一些很棒的截屏视频(尽管基于 Rails 2,但理论是相同的。)

Don't ever cache for the sake of it, cache because there's a need (with the exception of something like the homepage, which you know is going to be super popular.) Launch the site, and either parse your logs or use something like NewRelic to see what's slow. From there, you can work out what's worth caching.

Generally though, if something takes 500ms to complete, you should cache, and if it's over 1 second, you're probably doing too much in the request, and you should farm whatever you're doing to a background process…for example, fetching a Twitter feed, or manipulating images.

EDIT: See apneadiving's answer too, he links to some great screencasts (albeit based on Rails 2, but the theory is the same.)

稀香 2024-12-17 19:49:56

您需要考虑缓存几种类型的事情:

  • 频繁点击且很少更改的请求
  • 绘制“昂贵”的请求、大量数据库调用等。也希望这些很少更改。

缓存的另一个不容忽视的方面是过期。这通常也是最困难的部分。您必须知道缓存何时不再有效,并将其清除,以便生成新的内容。清理器或观察者可以帮助您完成此任务,具体取决于您实现缓存的方式。您也可以仅根据时间值来执行此操作,允许缓存具有最大期限,并在之后清除它们,无论如何。

至于片段与全页缓存,请根据这些部分的更新频率来考虑。如果页面的 3 个部分从未更新,其中一个是,也许您想要缓存这 3 个部分,并允许实时获取 1 个部分,以便您可以获得高达第二个精度。或者,如果页面的不同部分应该有不同的缓存规则:也许“时间线”部分被缓存,但缓存期限为 1 分钟。而“朋友”部分则缓存 12 小时。

希望这有帮助!

You'll want to think about caching several kinds of things:

  • Requests that are hit a lot, and seldom change
  • Requests that are "expensive" to draw, lots of database calls, etc. Also hopefully these seldom change.

The other side of caching that shouldn't go without mention, is expiration. Its also often the harder part. You have to know when a cache is no longer good, and clear it out so fresh content will be generated. Sweepers, or Observers, depending on how you implement your cache can help you with this. You could also do it just based on a time value, allow caches to have a max-age and clear them after that no matter what.

As for fragment vs full page caching, think of it in terms of how often those parts are updated. If 3 partials of a page are never updated, and one is, maybe you want to cache those 3, and allow that 1 to be fetched live for so you can have up to the second accuracy. Or if the different partials of a page should have different caching rules: maybe a "timeline" section is cached, but has a cache-age of 1 minute. While the "friends" partial is cached for 12 hours.

Hope this helps!

执妄 2024-12-17 19:49:56

如果网站活动相对较少,则不应缓存任何页面。您之所以进行缓存是因为性能问题,而性能问题的出现是因为您有太多的数据要查询、太多的用户,或者更糟糕的是,这两种情况同时发生。

考虑缓存之前,您要做的第一件事就是检查应用程序以查找占用最多时间的请求。不是最慢的请求,而是应用程序花费最多总时间执行的请求。也就是说,如果您有一个请求 A 以 1500 毫秒运行 10 次,请求 B 以 250 毫秒运行 5000 次,那么您首先要优化 B。

实际上,通过 product.log 进行 grep 并提取渲染时间和 URL 将它们合并到一个简单的报告中非常容易。如果您愿意,您甚至可以实时执行此操作。

一旦您确定了有问题的请求,您就可以开始分析它为满足该请求而采取的措施。第一件事是寻找可以通过使用预先加载或通过更多地预测来预测您需要的内容来组合的任何查询。接下来的事情是确保您没有加载未使用的数据。

很多时候,您会看到列出用户的代码,它会加载每人 50KB 的传记数据、他们的 Facebook 和 Twitter 账号,实际上是关于他们的一切,而您所使用的只是他们的名字。

根据需要获取尽可能少的内容,并以最有效的方式获取它。当您不需要模型时,请使用connection.select_rows

下一步是查看您正在运行什么类型的查询,以及它们的性能如何不佳。确保您的索引全部设置正确并且正在使用。检查您是否没有执行复杂的 JOIN 操作,这些操作可以通过一些战术非规范化来解决。

查看您在应用程序中存储的数据,并尝试查找可以从生产数据库中删除并存储在其他地方的数据。当数据不再相关时,定期将其循环出去,如果需要,将其保存在单独的数据库中。

然后查看一下您的数据库服务器是如何调优的。它有足够大的缓冲区吗?硬件上是否可以以名义成本升级为更多内存?太多人正在运行完全未经调整的数据库服务器,并且通过一些简单的设置,他们可以获得十倍的性能提升。

当且仅当您此时仍然存在性能问题时,您可能需要考虑缓存。

你知道为什么不先缓存吗?这是因为一旦缓存了某些内容,缓存的数据就会立即失效。如果应用程序的某些部分在假设数据始终是最新的情况下使用这些数据,那么您将会遇到问题。如果当数据发生更改时您没有使该缓存过期,则会遇到问题。如果您缓存数据并且不再使用它,那么您只会堵塞缓存并且会遇到问题。基本上,当您使用缓存时,您会遇到很多问题,因此它通常是最后的手段。

If the site is relatively low activity you shouldn't cache any page. You cache because of performance problems, and performance problems come about because you have too much data to query, too many users, or worse, both of those situations at the same time.

Before you even think about caching, the first thing you do is look through your application for the requests that are taking up the most time. Not the slowest requests, but the requests your application spends the most aggregate time performing. That is if you have a request A that runs 10 times at 1500ms and request B that runs 5000 times at 250ms you work on optimizing B first.

It's actually pretty easy to grep through your production.log and extract rendering times and URLs to combine them into a simple report. You can even do that in real-time if you want.

Once you've identified a problematic request, you go about picking apart what it's doing to service the request. The first thing is to look for any queries that can be combined by using eager loading or by looking ahead a bit more to anticipate what you'll need. The next thing is to ensure you're not loading data that isn't used.

So many times you'll see code to list users and it's loading 50KB per person of biographical data, their Facebook and Twitter handles, literally everything about them, and all you use is their name.

Fetch as little as you need, and fetch it in the most efficient way you can. Use connection.select_rows when you don't need models.

The next step is to look at what kind of queries you're running, and how they're under-performing. Ensure your indexes are all set properly and are being used. Check that you're not doing complicated JOIN operations that could be resolved by a bit of tactical de-normalization.

Have a look at what data you are storing in your application, and try and find things that can be removed from your production database and warehoused somewhere else. Cycle your data out regularly when it's no longer relevant, preserve it in a separate database if you need to.

Then go over and have a look at how your database server is tuned. Does it have sufficiently large buffers? Is it on hardware that could be upgraded with more memory at a nominal cost? Too many people are running a completely un-tuned database server and with a few simple settings they can get ten-fold performance increases.

If, and only if, you still have a performance problem at this point then you might want to consider caching.

You know why you don't cache first? It's because once you cache something, that cached data is immediately stale. If parts of your application use this data under the assumption it's always up to date, you will have problems. If you don't expire this cache when the data does change, you will have problems. If you cache the data and never use it again, you're just clogging up your cache and you will have problems. Basically you'll have lots of problems when you use caching, so it's often a last resort.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文