2011-10-08 52 views
2

首先,让我说明情况,我有以下几点:缓存(大和静态)与类变量数据

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

  • NODE_ID(唯一)
  • NODE_NAME(唯一)

并与以下属性 “NodeConnection” 级:

  • node_from
  • node_to

我们将有大约1〜3万个节点和周围的东西3 10万个NodeConnections。

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

在对Rails应用程序的每个请求中,我们必须通过可能的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)和静态(数据应用生命周期中有效地不会改变)的数据,因此所有轨道同一台机器内的实例可以非常快速地访问此缓存(!)?

+0

只是一个想法,不知道它的好还是坏 - 是否尝试过使用'Struct'而不是实际的类,或者使用自定义的C绑定?这也可以提高性能,我会看看 –

+0

。你可能有一些资源给C绑定的东西? – Deradon

+1

其他的上帝或坏主意:写一个小的C应用程序,在本地UNIX套接字上提供数据,并缓存数据本身 –

回答

2

这听起来像一个非常具体的情况,但为了避免每个进程的内存缓存(即你的类变量)需要自然加热,我会调查脚本的可行性温暖启动过程并从初始化程序中运行它...您的应用程序可能需要较长时间才能启动,但您的用户无需等待。

编辑|请注意,如果您正在使用诸如Unicorn之类的技术,该技术支持在派生工作进程之前预加载应用程序代码,那么可以将这种初始化的影响降至最低。

+0

感谢提示独角兽。我会试一试。 (对独角兽来说又多了一个机会:对于nginx和乘客有一些问题) – Deradon