使用延迟作业进行页面缓存

时间:2011-01-16 21:53:38

标签: ruby-on-rails caching optimization ruby-on-rails-3

嘿所有,如果您曾在[craigslist]上发帖,这个问题应该对您有意义。每当您发布商品(例如,出售家具或公寓)时,您的商家信息不会立即被列入网站。相反,列表将每10-15分钟分批出现(数量不同)。起初我真的过度思考这种行为,试图保存记录然后进行批量插入,但我意识到它更简单。在与一些同事交谈之后,Craigslist正在缓存他们的页面,然后每隔10-15分钟清空一次缓存。这严重降低了数据库的负载。

现在,我的问题。我如何在Rails中完成同样的事情?我知道如何实现缓存 - 我已经阅读了[使用Rails指南进行缓存]。我将使用动作缓存和片段缓存(因为我无法缓存整个页面)。我仍然需要进行验证和访问控制,因此我无法完全缓存页面...

3 个答案:

答案 0 :(得分:5)

要实现定时页面缓存,您可以使用标准的Rails缓存加上一点时间的聪明。

首先,您要确定缓存级别。你有三个选择:

  1. Page Caching - 缓存整个页面,但后续请求不会通过Rails堆栈。因此,如果这是一个Craiglist-esque页面,每秒会被命中几千次,那么这个请求只会发送到您的网络服务器(例如apache),而不是Rails,或者您的数据库会更快。权衡的是你丢失了Rails提供的身份验证,会话变量等。
  2. Action Caching - 缓存整个页面,但将请求带入Rails,以便它可以执行与该操作相关的任何过滤器。
  3. Fragment Caching - 缓存页面的一部分,基本上绕过了在块中执行代码的需要(以及对数据库的任何后续调用)。
  4. 然后,您需要选择适当级别的缓存并在您的应用中实现(请查看上面的链接以获取实施示例)。

    一旦实现了缓存,您现在必须找到一种使缓存过期的方法。我可以想到两种方法来做到这一点,都有好处和缺点。现在让我们假设你选择使用动作缓存。

    1. 可靠但更具参与性 - 在控制器中创建一个过期缓存的操作和一个对该操作发出请求的cron作业任务。我问了一个类似的问题来解决这个问题'built in' scheduled task。对于安全预防措施,您可能希望包含生成的哈希值或类似内容,以便有人无法通过转到'/ products / expire_cache'手动使缓存过期。

      class ProductsController < ApplicationController
        caches_action :index
      
        def index
          # implementation
        end
      
        def expire_cache
          if params[:verification_hash] == 'sa89sf8sfsfehiwaf89yfea98fh'
            expire_action :action => :index
          end
        end
      end
      
    2. 不可靠但更容易 - 只需使用任意条件使您的操作中的缓存失效。此实现假设将有足够的流量来定期确保有人将在0,15,30和45分钟内访问您的站点。您可以减少此间隔,以确保以更可能的间隔重置缓存。

      class ProductsController < ApplicationController
        caches_action :index
      
        def index
          # implementation
          expire_action :action => :index if Time.now.min % 15 == 0
        end
      end
      

答案 1 :(得分:0)

我认为您想要实现的目标有两种方法:

  1. 只需使用片段和操作进行缓存,以便在页面的第一次访问时访问数据库并正常加载页面,但每次后续命中都来自缓存版本。这种方法的主要优点是,您不需要处理延迟的作业,也不需要将页面呈现在常规流程之外。
  2. 创建一个延迟作业,呈现您的页面或缓存的各个片段。在延迟作业中呈现期间,页面片段实际上将被缓存,就像用户正在查看它们一样(前提是您已经正常实现了片段和操作缓存)。完成延迟作业后,填充数据库中的一列,指示此记录/页面已准备好供查看。

答案 2 :(得分:0)

caching in Rails的最简单方法可能是使用Memcached :expires_in选项。

您可能需要一台VPS服务器来使用它,这对于较小的站点来说可能很昂贵。

但即使没有memcached,你也可以做好基于时间的缓存。这个小SimpleCache代码段为我的共享托管网站创造了奇迹。