Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何在不占用(全部)内存的情况下,使用Rails(re)tire、json一次索引成吨的数据?_Ruby_Ruby On Rails 3.2 - Fatal编程技术网

Ruby 如何在不占用(全部)内存的情况下,使用Rails(re)tire、json一次索引成吨的数据?

Ruby 如何在不占用(全部)内存的情况下,使用Rails(re)tire、json一次索引成吨的数据?,ruby,ruby-on-rails-3.2,Ruby,Ruby On Rails 3.2,在Rails 3.2.x应用程序中,使用(Re)tire访问ES集群,rake任务将通过大约1百万行创建新索引。(Ruby 1.9.3) 该任务正在使用.to_json,其中列出了特定的属性和方法,以限制每个元素的结果哈希。 然而,当任务运行时,内存会被消耗掉,最终进程通常会被系统终止 该任务已在使用“逐批查找”。较小的批量(使用find_)没有帮助 无索引检查 删除index.import调用确实可以改善情况(显然)。这项任务很快就完成了整个集合,没有任何问题。指向ES、tire或JSON转换

在Rails 3.2.x应用程序中,使用(Re)tire访问ES集群,rake任务将通过大约1百万行创建新索引。(Ruby 1.9.3)

该任务正在使用.to_json,其中列出了特定的属性和方法,以限制每个元素的结果哈希。 然而,当任务运行时,内存会被消耗掉,最终进程通常会被系统终止

该任务已在使用“逐批查找”。较小的批量(使用find_)没有帮助

无索引检查 删除index.import调用确实可以改善情况(显然)。这项任务很快就完成了整个集合,没有任何问题。指向ES、tire或JSON转换(以及它可能调用的关系)

缩小任务范围 添加回index.import并为每个项传递非常有限的散列(带有字符串键),确实会使速度变慢,但不会消耗太多内存。所以json可能不是罪魁祸首

重新添加属性和方法 罪魁祸首似乎是用于获取一个附加属性的方法之一。这是基于模型和另一个。。。最终有很多模型被涉及和筛选

正如添加includes所指出的那样,这确实有点帮助,但任务最终也会很繁重

四处走动 我还尝试解决部分问题,并使用ES bulk API替换对Tire的调用。 生成json文件并使用Ruby http库发送它们是可行的。然而,同样的问题也出现了:内存,因为对数据库的请求是相同的

还剩下什么? 我不明白的是,为什么即使使用逐批查找的方法,Ruby也会不断消耗内存。我希望在每批数据之后,与该批数据相关的内存都会被释放

下一步尝试:GC.start调用,围绕任务的活动记录缓存取消激活

然而,除非有一种解决方案能大幅限制内存使用(300或500毫安,而不是800+),否则背景问题是:索引一个模型的许多实例,包括与其他一些模型相关的数据

  • 我是否遗漏了可以解决问题的导入和包含内容
  • 将任务拆分成更小的后台工作(resque、sidekiq)会有帮助吗?我想是这样的,因为每一批都会与其他批隔离开来,一旦处理完毕,就会真正释放内存(?(协调这些任务将是另一个麻烦)
  • 是否有与将大量数据索引到ES相关的良好实践

我使用Rails+Elasticsearch已经有一段时间了,而且这种舞蹈也跳了好几次。 我想到了几件事,没有特别的顺序

  • 您是否尝试使用最近的
    elasticsearch
    gem(而不是
    tire
    )?我已经更新了我的应用程序以供使用,并且喜欢对所做的事情有更多的控制

  • 我还尝试在每个ActiveRecord循环之后强制执行GC扫描。您还可以通过每次显式重置所有局部变量来格外小心内存分配

  • 您可以使用
    fork&exec
    技巧在每个循环中fork一个全新的进程,这将是您能得到的最有效的GC。当你第一次写它的时候,它会有一点开销,但是回报是巨大的。注意限制任务外部部分使用的内存量。使用基于进程的后台任务可以部分实现相同的目标,但仍然可能会导致内存膨胀

  • 你能限制ActiveRecord的使用吗?如果您需要一些基本的关联,您可以使用较低级别/更简单的工具,如Sequel(或else),来使用Ruby哈希/数组,而不是成熟的AR模型


  • 1.迁移到新的gem正在进行中,但如上所述,ES部分似乎与(内存)问题2和3无关:将尝试一下,谢谢!在Jesse Storimer的《使用Unix进程》一书中,您可以找到许多关于fork&exec的有价值的信息: