Какую пользу может принести кэш фрагмента Rail вашему приложению, т.е. предотвратить вызовы из базы данных? - PullRequest
0 голосов
/ 27 августа 2018

Информация в моем верхнем / нижнем колонтитуле получена из набора словарных таблиц в моей базе данных, и данные будут меняться крайне редко.Я думаю, что это идеальная возможность для кэширования, так что каждая страница не будет касаться базы данных в том, что касается рендеринга верхнего / нижнего колонтитула.

Руководство по 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-код кэшируется, но действительно ли процесс рендеринга является значительной экономией даже для большого фрагмента ??Я чувствую, что нагрузка на базу данных - это то, что вы действительно хотите ограничить, особенно если вы имеете дело с большим количеством одновременного трафика.

Какова подходящая стратегия кэширования для таких вещей, как нижний колонтитул / частичные элементы навигации .?

1 Ответ

0 голосов
/ 27 августа 2018

Пример 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 не самый лучший или вам нужны дополнительные действия.

Это будет кешировать только запрос (не уверенесли вам нужно кэшировать массив или кэширование запроса работает аналогично, может вам понадобится .to_a в конце), вы все равно можете использовать фрагментное кэширование, если вы тоже хотите кэшировать элементы li.

Я полагаю, вы могли бы даже кэшировать полный html категорий, поскольку низкоуровневый кеш принимает любую информацию, вам нужно только найти правильное место для использования Rails.cache.fetch и правильное место для сохранения / обновления ключа кэша.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...