首页 > 解决方案 > Rail 片段缓存如何使您的应用程序受益,即防止数据库调用?

问题描述

我的页眉/页脚中的信息来自我数据库中的一堆字典表,并且数据将很少更改。我认为这是缓存的绝佳机会,因此就呈现页眉/页脚而言,每个页面都不会触及数据库。

Rails 指南提供了片段缓存的示例,因此我认为我的导航链接将类似于...

<% @categories.each do |category| %>
  <% cache category do %>
    <li class="nav-link">
      <%= link_to category.name, category_path(category) %>
    </li>
  <% end %>
<% end %>

但我不明白这如何阻止与数据库的联系或优化任何东西。控制器在视图呈现之前调用@categories,这意味着每个页面请求都会进行SQL查询......一些HTML正在被缓存,但是即使对于更大的片段,呈现过程真的是一个显着的节省吗?我觉得数据库的压力是你真正想要限制的,尤其是在处理大量并发流量时。

页脚/导航部分的适当缓存策略是什么?

标签: ruby-on-railsrubycachingweboptimization

解决方案


Rails Guides 的片段缓存示例仅指缓存生成的视图以显示对象,而不是查询,这就是为什么您看不到它缓存查询的位置的原因,因为它没有。

您可以使用低级缓存来缓存@categories查询https://guides.rubyonrails.org/caching_with_rails.html#low-level-caching

它可以缓存任何类型的信息,所以,你可以有类似的东西

class Category < ActiveRecord::Base
  def self.for_navbar
    Rails.cache.fetch("#{nav_cache_key}/categories_for_navbar", expires_in: 1.week) do
      self.whatever_scope_you_need
    end
  end
end

您需要更改的是nav_cache_key用于标识缓存的 var。我不确定这个的最佳实践,但我会在你第一次需要它时使用当前时间戳设置一个类变量,并在应该擦除缓存时更新它。

就像是

def self.navbar_cache_key
  @@navbar_cache_key ||= Time.now
end

after_update :change_cache_key

def change_cache_key
  @@navbar_cache_key = Time.now
end

这样,每次更新类别时,它都会更改@@navbar_cache_key类的值,并且缓存将为新键更新。我不确定缓存需要更新的真实条件是什么,也许after_update回调不是最好的,或者您需要一些额外的操作。

这将只缓存查询(不确定您是否需要缓存数组或缓存查询的工作方式相同,可能最后需要 a .to_a),如果您也想缓存li元素,您仍然可以使用片段缓存。

我想您甚至可以缓存类别的完整 html,因为低级缓存接受任何类型的信息,您只需要找到正确的使用Rails.cache.fetch位置以及保存/更新缓存键的正确位置。


推荐阅读