【问题标题】:Rails Caching in Agile Web Development w/ Rails4使用 Rails4 实现敏捷 Web 开发中的 Rails 缓存
【发布时间】:2014-04-22 04:06:15
【问题描述】:

我正在阅读《使用 Rails4 进行敏捷 Web 开发》一书,我刚刚阅读了关于缓存部分视图以避免压倒数据库的(第一)部分。 我当然在开发环境的配置中将缓存选项设置为 true。

问题是缓存似乎不起作用。 这是我的 app/views/store/index.html.erb 文件,与书中给出的完全相同,用于启用缓存:

<% if notice %>
  <p id="notice"><%= notice %></p>
<% end %>

<h1>Your Pragmatic Catalog</h1>

<% cache ['store', Product.latest] do %>
  <% @products.each do |product| %>
    <% cache ['entry', product] do %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <%= sanitize(product.description) %>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
        </div>
      </div>
    <% end %>
  <% end %>
<% end %>

这里是 rails 服务器日志,清楚地表明数据库被多次访问(尽管有一行提到缓存):http://pastebin.com/v2jGiHKL

这是我的 app/views/store/index.html.erb 文件,我在其中尝试了其他缓存:

<% if notice %>
  <p id="notice"><%= notice %></p>
<% end %>

<h1>Your Pragmatic Catalog</h1>

<% cache('caching') do %>
  <% @products.each do |product| %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <%= sanitize(product.description) %>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
        </div>
      </div>
  <% end %>
<% end %>

这里是对应的日志,显示缓存成功(因为没有查询到数据库):http://pastebin.com/ZTk9A9RA

有人可以解释为什么一个似乎工作而不是另一个,或者第一个应该如何工作?谢谢你:)

请注意,书中说启用缓存后,如果更改是在缓存块内进行的,则重新加载商店页面不应显示 store/index.html.erb 的新部分;但在这两种情况下都是如此。有什么想法吗?

【问题讨论】:

  • 在您的第一个日志中只有一个GET "/"。你能告诉我们控制器吗?
  • 是不是因为第二种情况我只访问了一次页面,第一种情况我只访问了两次? (在这种情况下,你的意思是相反的,对吧?)无论如何,这是我的控制器:pastebin.com/J6dpxe7Dpastebin.com/aKTUFX82

标签: ruby-on-rails ruby caching ruby-on-rails-4


【解决方案1】:

您传递给cache api 的参数是缓存键。该键的散列函数是缓存片段的存储位置以及查找位置。

在您的代码 (cache('caching')) 中,缓存键是硬编码的,并且永远不会更改,因此,除非缓存无效(在您的代码中手动或当其 TTL 已过) - 相同的片段将被发送给客户。

在书中的代码 (cache ['store', Product.latest]) 中,密钥取决于最新产品。这意味着如果最新产品发生变化(添加或更新了另一个产品) - 下一次调用将自动“知道”不是从缓存中获取页面,而是重新创建缓存。

日志中显示的内容:

[1m[35mProduct Load (0.3ms)[0m  SELECT  "products".* FROM "products"   ORDER BY "products"."updated_at" DESC LIMIT 1

实际上是Product.latest的结果,不是Product.all

总结一下 - 两个代码片段都被缓存了,但是在示例代码中, 对数据库进行了一次(小)命中,以验证缓存的有效性,无论页面是否被缓存或不是。

如果您自己使缓存失效,您可以保留代码的硬编码版本,但如果不是,您最好考虑一个失效方案,无论是像示例代码建议的那样还是其他什么。

【讨论】:

  • 好的,我明白了,非常感谢 :) 所以在 Rails 中,是否更常见的是使用每次在数据库中更改重要内容时调用的函数来“手动”使缓存无效,或者最好让缓存的片段使用动态键自行处理?
  • 我认为这里有一些变量,具体取决于用例(显示 最新 数据与数据库可以“承受”多少负载的重要性) ,但我相信除非您真的担心您的数据库,否则让完成这项工作可能会更简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
相关资源
最近更新 更多