нумерация страниц и memcached в рельсах - PullRequest
2 голосов
/ 18 сентября 2010

Каков наилучший способ кэширования разбитого на страницы набора результатов с помощью rails и memcached?

Например, контроллер сообщений :

def index
  @posts = Rails.cache.fetch('all_posts') do
    Post.paginate(:conditions => ['xx = ?', yy], :include => [:author], :page => params[:page], :order => 'created_at DESC')
  end
end

Очевидно, что это не работает при изменении params[:page]. Я могу изменить ключ на "all_posts_#{params[:page]}_#{params[:order]_#{last_record.created_at.to_i}", но тогда может быть несколько возможных заказов (недавние, популярные, большинство проголосовавших и т. Д.), И будет комбинация страниц и заказов ... много ключей таким образом.

Проблема №2. Кажется, что когда я реализую это решение, кэши записываются правильно, и страница прекрасно загружается при первом вызове действия с разбиением на страницы. Когда я снова нажимаю на ту же страницу, т.е. страницу 1, с порядком recent, кажется, что браузер даже не звонит на сервер. Я не вижу никакого действия контроллера, вызываемого в журнале производства.

Я использую пассажир, РЗЭ, memcached и рельсы 2.3.5. Firebug не показывает никаких запросов ....

Есть ли простой / более изящный способ справиться с этим?

1 Ответ

0 голосов
/ 19 сентября 2010

Когда дело доходит до кэширования, не существует простого решения. Вы можете кэшировать каждый вариант результата, и это нормально, если вы реализуете автоматическое истечение срока действия записей. Вы не можете просто использовать all_posts, потому что таким образом вам придется истечь десятки ключей, если посты будут изменены.

Каждый экземпляр модели AR имеет ключ .cache_key, основанный на методе updated_at, который является предпочтительным способом, поэтому используйте его вместо последней записи. Также не основывайте свой ключ на последней записи, потому что если какой-либо пост в середине будет удален, ваш ключ не изменится. Вместо этого вы можете использовать такую ​​логику.

class ActiveRecord::Base         
  def self.newest
    order("updated_at DESC").first
  end    
  def self.cache_key
    newest.nil? ? "0:0" : "#{newest.cache_key}:#{count}"
  end
end

Теперь вы можете использовать Post.cache_key, который будет изменен, если какое-либо сообщение будет изменено / удалено или создано.

В общем, я бы просто кешировал Post.all и затем разбивал на страницы этот объект. Вам действительно нужно выполнить некоторое профилирование, чтобы найти узкие места в вашем приложении.

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

Если решать, как и где кэшировать. Здесь нет одностороннего

Что касается второй части вопроса, у меня есть несколько подсказок, чтобы найти ответ. Проверьте, звонит ли браузер всем LiveHTTPHeaders, tcpdump и т. Д.

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