【问题标题】:pagination and memcached in railsRails 中的分页和内存缓存
【发布时间】:2010-09-17 22:41:23
【问题描述】:

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

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

有没有更简单/更优雅的处理方式?

【问题讨论】:

    标签: ruby-on-rails memcached


    【解决方案1】:

    在缓存方面没有简单的解决方案。您可以缓存结果的每个变体,如果您实现条目的自动过期,那就没问题了。您不能只使用 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 等。

    【讨论】:

    • 谢谢。对于第二个问题,我认为另一个问题可能会给您更多提示。 stackoverflow.com/questions/3743268/…。出于某种原因,即使我没有在我的 rails 应用程序中做任何事情,max-age 也会被设置,仍然试图理解问题。我听说 nginx 也是一个反向代理,可能与此有关?
    • 使用这种“order("updated_at DESC").first”方法,每次请求进入时都会运行该查询吗?
    • 是的,它每次都会运行,除非你将它与另一个缓存方法结合起来。但总的来说,没有其他方法可以做到这一点。您必须通过查看数据库来检查缓存是否有效。但在大多数情况下,无论如何这都会加快速度。
    猜你喜欢
    • 2014-03-13
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2012-01-12
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多