Ruby 如何在不占用(全部)内存的情况下,使用Rails(re)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+),否则背景问题是:索引一个模型的许多实例,包括与其他一些模型相关的数据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转换
- 我是否遗漏了可以解决问题的导入和包含内容
- 将任务拆分成更小的后台工作(resque、sidekiq)会有帮助吗?我想是这样的,因为每一批都会与其他批隔离开来,一旦处理完毕,就会真正释放内存(?(协调这些任务将是另一个麻烦)
- 是否有与将大量数据索引到ES相关的良好实践
elasticsearch
gem(而不是tire
)?我已经更新了我的应用程序以供使用,并且喜欢对所做的事情有更多的控制fork&exec
技巧在每个循环中fork一个全新的进程,这将是您能得到的最有效的GC。当你第一次写它的时候,它会有一点开销,但是回报是巨大的。注意限制任务外部部分使用的内存量。使用基于进程的后台任务可以部分实现相同的目标,但仍然可能会导致内存膨胀1.迁移到新的gem正在进行中,但如上所述,ES部分似乎与(内存)问题2和3无关:将尝试一下,谢谢!在Jesse Storimer的《使用Unix进程》一书中,您可以找到许多关于fork&exec的有价值的信息: