ActiveRecord批量数据,内存永远增长

jro*_*ind 5 memory activerecord bulkinsert ruby-on-rails

我正在使用 ActiveRecord 将一些数据从一个数据库中的表批量迁移到另一个数据库中的不同表。大约 400 万行。

我正在使用 find_each 批量获取。然后,我对获取的每条记录执行一些逻辑,并将其写入不同的数据库。我尝试过直接一一写入,也尝试过使用漂亮的 activerecord-import gem 来批量写入。

然而,无论哪种情况,我的 ruby​​ 进程内存使用量在导出/导入的整个生命周期中都会增长相当多。我认为使用 find_each 时,我会得到 1000 个批次,内存中一次应该只有 1000 个...但是不,我获取的每条记录似乎都会永远消耗内存,直到该过程结束。

有任何想法吗?ActiveRecord 是否在某处缓存了我可以关闭的内容?

更新于 2012 年 1 月 17 日

我想我会放弃这个。我已经尝试过: * 确保所有内容都包含在ActiveRecord::Base.uncached do * 添加中ActiveRecord::IdentityMap.enabled = false(我认为应该关闭当前线程的身份映射,尽管没有明确记录,而且我认为当前 Rails 中默认情况下身份映射不是打开的无论如何)

这些似乎都没有多大作用,内存仍然泄漏。

然后我添加了一个周期性显式:

  • GC.start

这似乎减慢了内存泄漏的速度,但内存泄漏仍然发生(最终耗尽所有内存并轰炸)。

所以我想我要放弃,并决定目前不可能使用 AR 从一个数据库读取数百万行并将它们插入到另一个数据库中。也许正在使用的 MySQL 特定代码(即我的数据库)或 AR 中的其他地方存在内存泄漏,或者谁知道呢。

小智 1

我建议将每个工作单元排队到Resque 队列中。我发现 ruby​​ 在迭代像这样的大型数组时有一些怪癖。

让一个主线程按 ID 对工作进行排队,然后让多个 resque 工作线程访问该队列来完成工作。

我已经在大约 30 万条记录上使用了这种方法,因此它很可能会扩展到数百万条。