首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在将Rails应用程序从mongoid (MongoDB)迁移到ActiveRecord (Postgres)时,如何获得恒定的内存使用量?

在将Rails应用程序从mongoid (MongoDB)迁移到ActiveRecord (Postgres)时,如何获得恒定的内存使用量?
EN

Stack Overflow用户
提问于 2019-05-30 19:12:42
回答 1查看 304关注 0票数 6

我最近开始咨询和帮助开发一个Rails应用程序,该应用程序使用MongoDB (将Mongoid作为其DB客户端)来存储其所有模型实例。

在应用程序处于早期启动阶段时,这是很好的,但随着应用程序获得越来越多的客户端,并且开始需要越来越复杂的查询来在界面中显示适当的统计数据和其他信息,我们决定唯一可行的解决方案是标准化数据,并转而使用结构化数据库。

因此,我们现在正在将表和数据从MongoDB (使用Mongoid作为对象映射器)迁移到Postgres (使用ActiveRecord作为对象映射器)。因为我们必须确保Mongo数据库中没有不正确的非规范化数据,所以我们必须在Rails-land中运行这些数据迁移,以确保正在运行验证、回调和健全性检查。

开发过程一切顺利,但现在我们在一个临时服务器上运行迁移,使用的是真正的生产数据库。事实证明,对于某些迁移,服务器的内存使用量随着模型实例的数量线性增加,导致一旦我们填满了16 GB的RAM (以及另外16 GB的交换空间...),迁移就会终止。

由于我们一个接一个地迁移模型实例,我们希望能够找到一种方法来确保内存使用量能够保持(接近)恒定。

(a) ActiveRecord或Mongoid保持对我们已经导入的对象实例的引用,以及(b)迁移在单个数据库事务中运行,因此Postgres占用越来越多的内存,直到它完成?

所以我的问题是:

  • 这种线性内存使用的可能原因是什么?
  • 我们如何减少它?
  • 有没有办法让Mongoid和/或ActiveRecord放弃我们试图手动调用Ruby的旧Ruby?
  • 有没有办法将数据迁移拆分成多个数据库事务,这会有帮助吗?

这些数据迁移具有以下格式:

class MigrateSomeThing < ActiveRecord::Migration[5.2]
  def up
    Mongodb::ModelName.all.each do |old_thing| # Mongoid's #.all.each works with batches, see https://stackoverflow.com/questions/7041224/finding-mongodb-records-in-batches-using-mongoid-ruby-adapter 
      create_thing(old_thing, Postgres::ModelName.new)
    end
    raise "Not all rows could be imported" if MongoDB::ModelName.count != Postgres::ModelName.count
  end

  def down
    Postgres::ModelName.delete_all
  end

  def create_thing(old_thing, new_thing)
    attrs = old_thing.attributes
    # ... maybe alter the attributes slightly to fit Postgres depending on the thing.
    new_thing.attributes = attrs
    new_thing.save!
  end

end
EN

回答 1

Stack Overflow用户

发布于 2019-05-31 08:09:37

我建议通过执行所有读取,但不执行任何模型创建/写入,并查看内存使用量是否仍在增长,来缩小读取或写入端的内存消耗(或者,换句话说,Mongoid与AR)。

默认情况下,Mongoid批量执行查找,这与AR不同,AR必须通过find_in_batches请求。

由于默认情况下ActiveRecord迁移被包装在事务中,并且如果事务提交失败,AR将执行属性值跟踪以将模型实例的属性恢复为其先前的值,因此很可能正在创建的所有AR模型都保留在内存中,并且在迁移完成之前无法对其进行垃圾收集。可能的解决方案包括:

  1. 为有问题的迁移禁用隐式事务(https://apidock.com/rails/ActiveRecord/Migration):

通过直接插入的disable_ddl_transaction!

的库。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56377173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档