记一次Django内存占用问题的解决

举报
xenia 发表于 2019/10/12 16:03:55 2019/10/12
【摘要】 最近因为业务需要把MySQL中的大表迁移到HBase,在实际做数据迁移的过程中,总发现迁移脚本内存占用暴涨,已读达到70G,并最终导致整个线上机器因为OOM Killer杀掉了大部分的后台进程。代码也比较简单,类似如下。obj_qs = DataModel.objects.filter(created_time__gte=start_time, created_time__lt=end_ti...

最近因为业务需要把MySQL中的大表迁移到HBase,在实际做数据迁移的过程中,总发现迁移脚本内存占用暴涨,已读达到70G,并最终导致整个线上机器因为OOM Killer杀掉了大部分的后台进程。代码也比较简单,类似如下。

obj_qs = DataModel.objects.filter(created_time__gte=start_time, created_time__lt=end_time)
for item in obj_qs:
  put_data_to_hbase(item)

上面的是个示例代码,不过已经足以说明问题了。简单的几行代码跑一个月的数据,从运行开始内存占用就不断飙升。实际数据量不过几百万, 一开始怀疑写入hbase的地方内存没有释放,但代码注释掉在循环里空着继续跑的时候,内容还是暴涨。这才定位到是Django QuerySet的问题。官方文档对这个问题的描述如下。

A QuerySet typically caches its results internally so that repeated evaluations do not result in additional queries; iterator() will instead read results directly, without doing any caching at the QuerySet level. For a QuerySet which returns a large number of objects, this often results in better performance and a significant reduction in memory

原来每次数据库查询出的QuerySet对象都会结果进行缓存,方便下次再次查询的时候直接使用结果。但是对于我们这样的一锤子买卖来说,这缓存显然是不必要的。代码做如下改变问题就能得到解决。

obj_qs = DataModel.objects.filter(created_time__gte=start_time, created_time__lt=end_time).iterator()
for item in obj_qs:
  put_data_to_hbase(item)


本文转载自异步社区

原文链接:https://www.epubit.com/articleDetails?id=N9567f47c-3e9c-4655-a8df-526069928153

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。