【问题标题】:Django bulk_create ignore_conflicts=True leaks memoryDjango bulk_create ignore_conflicts=True 泄漏内存
【发布时间】:2020-11-22 01:35:36
【问题描述】:

我们正在使用 Django 2.2、python 3.6 和 mysql 5.6 来安排数据密集型作业。

长时间运行的作业的内存会随着时间的推移而增加。 DEBUG=False 在 settings.py 中

为什么要使用 ignore_conflicts?

我们为表设置了唯一键,所以ignore_conflicts可以过滤掉表中已经存在的那些记录。

这样的简单代码

for record_batch in readFromSomewhere(batch_size):
    for record in record_batch:
        product = parse(record)
        product_list.append(product)
    
    # memory increase and leak
    Product.objects.bulk_create(product_list, ignore_conflicts=True) 
    
    # memory does not increase
    #Product.objects.bulk_create(product_list)  

    #db.reset_queries()
    #gc.collect()

我读了很多stackoverflow帖子并放了gc.collect()django.db.reset_query(),但这并不能阻止增加。 如果我使用Product.objects.bulk_create(products),内存不会增加。 但如果我使用Product.objects.bulk_create(products,ignore_conflicts=True),内存会随着时间的推移而增加。

批量非常小,大约 100 个。 我注意到如果批处理大小更小,这意味着 bulk_create 调用的数量更大,内存增加得更快。如果batch size越大,内存增加越慢。

批量创建后(ignore_conflict=True)释放内存到数据库有什么想法吗?

【问题讨论】:

    标签: python django memory-leaks bulkinsert django-celery


    【解决方案1】:

    通过挖掘内存找到了根本原因。 我们使用的是 mysqlclient==1.3.14 包。这个包包含警告检查。 这些警告消息被保存到内存中,永远不会被垃圾收集。

    他们在新版本发布后直接从包中删除了所有警告检查。 所以升级到mysqlclient==1.4.4后,内存就稳定了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-05
      • 2020-07-13
      • 2014-08-09
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多