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

标签 ruby-on-rails ruby caching memcached

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

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

  • node_id(唯一)
  • 节点名称(唯一)

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

  • node_from
  • node_to

我们将拥有大约 1 到 300 万个节点和大约 3 到 1000 万个 NodeConnections。

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

在对 Rails 应用程序的每个请求中,我们必须通过可能的节点名称查找大约 10 到 100 个节点 ID。我们必须查找几百到几千个 node_connections。

我们目前在没有任何缓存的情况下对此进行了原型(prototype)设计(因此,大量的数据库查询)并且响应时间非常糟糕(比如 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 实例都可以非常快速地访问此缓存(!)?

最佳答案

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

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

关于ruby-on-rails - 使用类变量缓存(大型和静态)数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7698049/

相关文章:

ruby-on-rails - 带 capybara 的 cucumber 只得到空白页

ruby-on-rails - 如何调试 AWS S3 "Access Denied"

ruby - 更新 Ruby gems 的各种方法

ios - 在 iOS 上自动清除(清空/清除)缓存文件夹

html - W3 Total Cache 搞砸了我在 Godaddy 上托管的移动网站

eclipse - 如何清除 Eclipse p2 存储库缓存

ruby-on-rails - 每当 Gem AWS Elastic Beanstalk

ruby-on-rails - rails 控制台要求 nokogiri 返回 false(但在 irb 中工作)

ruby - 如何创建带有文本的PNG文件?

ruby - 使用 ruby​​ rake 运行 windows cmd