【问题标题】:Mongoid identity_map and memory usage, memory leaksMongoid identity_map 和内存使用,内存泄漏
【发布时间】:2016-07-26 12:38:10
【问题描述】:

当我执行查询时

 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 .. 期间使用的内存量? 非常感谢你的帮助!!!!

【问题讨论】:

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


    【解决方案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
    

    结论

    为记录分配的所有内存将永远不会被释放 查询请求。因此,尝试每次使用少量记录 请求完成了这项工作,并且内存状况良好,因为它将 每次请求后发布。

    【讨论】:

      【解决方案2】:

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

      Mymodel.all.each
      

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

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

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

      1. 翻阅所有模型,这样您一次只能使用合理数量的模型。
      2. 使用mapReduce 或聚合框架将逻辑推送到数据库中。

      当您处理真实数据(即不是非常小的数据库)时,您应该将尽可能多的工作推入数据库,因为数据库是为管理和操作大量数据而构建的。

      【讨论】:

      • 嗨!谢谢您的回答。 ` 我试过 Mymodel.each 做 ` 没有all 它使用同样大量的mamory 并最终压碎。你介意向我展示如何在 Mongoid 中通过 mapReduce 实现 Mymodel.each do 的示例!!!
      • 执行Mymodel.each 也会将它们全部加载。就像我说的,您需要将“做某事”步骤翻译成 MongoDB 能够理解的形式,然后才能使用 mapReduce 或聚合框架。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 2010-12-02
      • 2013-11-08
      • 2016-05-03
      • 2011-11-25
      • 2010-11-19
      • 2014-09-27
      相关资源
      最近更新 更多