在rails中分页和memcached

时间:2010-09-17 22:41:23

标签: ruby-on-rails memcached

使用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 - 当我实现此解决方案时,似乎正确编写了缓存,并且在第一次调用分页操作期间页面加载正常。当我点击同一页面,即page1,按recent顺序时,浏览器似乎甚至没有调用服务器。我没有在生产日志中看到任何控制器操作。

我正在使用乘客,REE,memcached和rails 2.3.5。 Firebug没有显示任何请求....

是否有一种简单/更优雅的方式来处理它?<​​/ p>

1 个答案:

答案 0 :(得分:0)

在缓存方面,没有简单的解决方案。您可以缓存结果的每个变体,如果您实现条目的自动过期,那就没问题。你不能只使用all_posts,因为如果帖子发生变化,你将不得不使用几十个密钥。

每个AR模型实例都有基于updated_at方法的.cache_key,这是首选方式,因此请使用此方法而不是最后一条记录。也不要将你的密钥放在最后一条记录上,因为如果中间的某些帖子被删除,你的密钥就不会改变。您可以使用这样的逻辑。

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等上进行调用。