Mongoid identity_map和内存使用,内存泄漏

时间:2014-12-04 15:31:12

标签: ruby-on-rails mongodb memory-leaks mongoid

执行查询时

 Mymodel.all.each do |model|
# ..do something  
end

它使用了大量的内存和已用内存的数量一直在增加并且崩溃了。我发现要修复它我需要禁用identity_map但是当我添加到mongoid.yml文件identity_map_enabled: false时我收到错误

Invalid configuration option: identity_map_enabled.
Summary:
  A invalid configuration option was provided in your mongoid.yml, or a typo is potentially present. The valid configuration options are: :include_root_in_json, :include_type_for_serialization, :preload_models, :raise_not_found_error, :scope_overwrite_exception, :duplicate_fields_exception, :use_activesupport_time_zone, :use_utc.
Resolution:
  Remove the invalid option or fix the typo. If you were expecting the option to be there, please consult the following page with repect to Mongoid's configuration:
  

I am using Rails 4 and Mongoid 4, Mymodel.all.count => 3202400

如何修复它或者某些人知道减少执行查询期间使用的内存量的其他方法.all.each ..? 非常感谢你的帮助!!!!

2 个答案:

答案 0 :(得分:1)

我开始使用与你一样的东西,通过数百万条记录进行循环,内存不断增加。

原始代码:

@portal.listings.each do |listing|
  listing.do_something
end

我已经通过了许多论坛答案,我试了一下。

第一次尝试:我尝试使用WeakRefGC.start的组合,但没有运气,我失败了。

第二次尝试:在第一次尝试时添加listing = nil,但仍然失败。

成功尝试

@start_date  = 10.years.ago
@end_date = 1.day.ago

while @start_date < @end_date
  @portal.listings.where(created_at: @start_date..@start_date.next_month).each do |listing|
    listing.do_something
  end

  @start_date = @start_date.next_month
end

<强>结论

  

在此期间永远不会释放为记录分配的所有内存   查询请求。因此,每次尝试少量记录   请求完成工作,内存状况良好,因为它会   在每次请求后发布。

答案 1 :(得分:0)

您的问题不是身份地图,我不认为Mongoid4甚至内置了身份地图,因此当您尝试将其关闭时会出现配置错误。您的问题是您正在使用all。当你这样做时:

Mymodel.all.each

Mongoid将尝试在db.mymodels集合中将每个单个文档实例化为Mymodel实例,然后再开始迭代。你说集合中有大约320万个文档,这意味着Mongoid将尝试在尝试迭代之前创建320万个模型实例。大概你没有足够的内存来处理那么多对象。

您的Mymodel.all.count工作正常,因为它只是向数据库发送一个简单的count调用并返回一个数字,它根本不会实例化任何模型。

解决方案是不使用all(并且最好忘记它存在)。根据“做某事”的作用,您可以:

  1. 浏览所有模型,以便您一次只使用合理数量的模型。
  2. 使用mapReduce或聚合框架将逻辑推入数据库。
  3. 每当您使用真实数据(即除了一个非常小的数据库之外的其他东西)时,您应该尽可能多地将数据推送到数据库中,因为数据库是为了管理和操作大量数据而构建的。