大文件上传到Django Rest Framework

2024-04-05

我尝试在 DRF 视图集上使用 PUT 上传一个大文件 (4GB)。

在上传过程中我的记忆是稳定的。在 100% 时,python runserver 进程占用越来越多的 RAM,并被内核终止。我有一条日志记录线put这个方法APIView但进程在该方法调用之前被终止。

我使用此设置来强制使用文件FILE_UPLOAD_HANDLERS = ["django.core.files.uploadhandler.TemporaryFileUploadHandler"]

这个内存峰值从何而来?我猜它会尝试将文件内容加载到内存中,但为什么(以及在哪里)?

更多信息:

  • 我尝试过 DEBUG true 和 false
  • runserver位于traefik后面的docker中,但traefik AFAIK没有限制并且上传达到100%
  • 我还不知道我是否会得到同样的行为daphne而不是运行服务器
  • 编辑:前面使用Content-Type multipart/form-data
  • 编辑:我已经尝试过FileUploadParser and (FormParser, MultiPartParser)对于我的 parser_classesAPIView

TL;DR:

既不是 DRF 也不是 Django 问题,这是一个已知达芙妮问题 2.5 年 https://github.com/django/daphne/issues/126。解决办法是暂时使用 uvicorn、hypercorn 或者其他的东西。

说明

您在这里看到的内容不是来自 Django Rest Framework,如下所示:

  • FileUploadParser 用于处理大文件上传,如它逐块读取文件 https://github.com/encode/django-rest-framework/blob/335054a5d36b352a58286b303b608b6bf48152f8/rest_framework/parsers.py#L177-L183;
  • 您的视图未执行排除了解析器在您访问之前不会执行request.FILES https://github.com/encode/django-rest-framework/blob/5828d8f7ca167b11296733a2b54f9d6fca29b7b0/rest_framework/request.py#L436-L443财产

你提到达芙妮的事实让我想起了这一点所以答案 https://stackoverflow.com/a/55237320/2441358其中提到了类似的问题,并指出 Daphne 不处理大文件上传的代码它加载了整个身体在将其传递给视图之前先将其存储在 RAM 中。 (在撰写本文时,代码仍然存在于其主分支中)

您会看到相同的行为runserver因为安装后,Daphne 会将初始的 runserver 命令替换为自身,以提供用于开发目的的 WebSockets 支持。

为了确保它是真正的罪魁祸首,请尝试禁用 Channels/运行默认的 Django runserver,并亲自查看您的应用程序是否被 OOM Killer 杀死。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大文件上传到Django Rest Framework 的相关文章

随机推荐