使用类变量缓存(大型和静态)数据

时间:2011-10-08 16:08:30

标签: ruby-on-rails ruby caching memcached

首先,让我解释一下情况,我有以下几点:

具有以下属性的“节点”类:

  • node_id(唯一)
  • node_name(唯一)

具有以下属性的“NodeConnection”类:

  • node_from
  • node_to

我们将拥有大约1到3百万个节点以及大约3到1千万个NodeConnections。

导入节点和连接一次后,将不会更改

在对Rails-Application的每个请求中,我们必须通过可能的node_names查找大约10到100个node_id。我们必须查找几百到几千个node_connections。

我们目前没有任何缓存原型(因此,很多数据库查询)和响应时间非常糟糕(如2分钟)。 所以我们通过 memcached 切换到缓存节点和连接。

性能提升,但仍然缺乏性能。 (因为我们为每个NodeConnection调用Cache.read,即每个请求几千个调用)

现在,我们尝试通过 Classvariable 进行缓存,并获得了巨大的性能提升。 (响应时间在几百毫秒内)

# Pseudocode below
class Node
  def nodes
    @@nodes ||= get_nodes
  end
  def node_connections
    @@node_connections ||= get_node_connections
  end
end

所以,我想问一下这个解决方案的优点缺点

缺点我还没有:

  • 每个Rails实例都必须建立自己的缓存(它自己的ClassVariables) - >更高的总内存使用量
  • 初始化缓存非常耗时(1-3分钟),因此我们无法在请求中执行此操作

其他任何解决方案都可以高效缓存大型(> 100MB)和静态(数据在应用程序生命周期内不会更改)数据,因此同一台计算机中的所有rails实例都可以非常快速地访问此缓存(!)?< / p>

1 个答案:

答案 0 :(得分:3)

这听起来像是一个非常特殊的情况,但是为了避免需要每个进程的内存缓存(即你的类变量)来自然地预热,我将研究编写温暖脚本的可行性 - 启动过程并从初始化程序中运行...您的应用程序可能需要更长时间才能启动,但您的用户无需等待。

编辑|请注意,如果您使用的是Unicorn,它支持在分配工作进程之前预先加载应用程序代码,则可以最大限度地减少此类初始化的影响。