2010-09-17 3 views
2

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

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

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, кажется, что браузер даже не звонит на сервер. Я не вижу, чтобы какое-либо действие контроллера вызывалось в журнале производства.

Я использую пассажирские, REE, memcached и rails 2.3.5. Firebug не показывает, что запросы не были сделаны ....

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

ответ

0

Когда дело доходит до кэширования, нет простого решения. Вы можете кэшировать каждый вариант результата, и это нормально, если вы реализуете автоматическое истечение записей. Вы не можете просто использовать 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 и т. Д.

+0

Спасибо. Для второй проблемы, я думаю, этот другой вопрос может дать вам больше намеков. http://stackoverflow.com/questions/3743268/max-age-with-nginx-passenger-memcached-rails2-3-5. по какой-то причине максимальный возраст устанавливается, хотя я ничего не делаю в своем приложении rails, все еще пытаюсь понять проблему. Я слышал, что nginx - это обратный прокси-сервер, возможно, он имеет какое-то отношение к этому? – badnaam

+0

с этим "заказом (" updated_at DESC "). Первый подход, будет ли этот запрос запускаться каждый раз, когда приходит запрос? – badnaam

+0

Да, он будет запускаться каждый раз, если вы не объедините это с другим кэшированием. Но вообще нет другого способа сделать это. Вы должны проверить, действителен ли кеш, просматривая вашу базу данных. Но в большинстве случаев эта скорость все равно. – mdrozdziel