programing

콘텐츠 길이 헤더없이 S3로 파일 업로드를 스트리밍 할 수 있습니까?

javaba 2021. 1. 15. 19:09
반응형

콘텐츠 길이 헤더없이 S3로 파일 업로드를 스트리밍 할 수 있습니까?


메모리가 제한된 컴퓨터에서 작업 중이며 동적으로 생성 된 (디스크에서 제외) 파일을 스트리밍 방식으로 S3에 업로드하고 싶습니다. 즉, 업로드를 시작할 때 파일 크기를 모르지만 마지막에 알 수 있습니다. 일반적으로 PUT 요청에는 Content-Length 헤더가 있지만 다중 부분 또는 청크 콘텐츠 유형을 사용하는 것과 같은 방법이있을 수 있습니다.

S3는 스트리밍 업로드를 지원할 수 있습니다. 예를 들어 다음을 참조하십시오.

http://blog.odonnell.nu/posts/streaming-uploads-s3-python-and-poster/

내 질문은 업로드 시작시 파일 길이를 지정하지 않고도 동일한 작업을 수행 할 수 있습니까?


S3의 멀티 파트 API 를 통해 5MiB + 청크로 파일을 업로드해야합니다 . 이러한 각 청크에는 Content-Length가 필요하지만 엄청난 양의 데이터 (100MiB +)를 메모리에로드하지 않아도됩니다.

  • S3 멀티 파트 업로드를 시작합니다 .
  • 해당 버퍼가 S3의 청크 크기 하한 (5MiB)에 도달 할 때까지 데이터를 버퍼에 수집합니다. 버퍼를 구축하는 동안 MD5 체크섬을 생성합니다.
  • 해당 버퍼를 Part 로 업로드 하고 ETag를 저장합니다 (해당 문서 읽기).
  • 데이터의 EOF에 도달하면 마지막 청크 (5MiB보다 작을 수 있음)를 업로드합니다.
  • 멀티 파트 업로드를 완료합니다.

S3는 최대 10,000 개의 부품을 허용합니다. 따라서 5MiB의 부분 크기를 선택하면 최대 50GiB의 동적 파일을 업로드 할 수 있습니다. 대부분의 사용 사례에 충분합니다.

그러나 더 필요하면 부품 크기를 늘려야합니다. 더 높은 부품 크기 (예 : 10MiB)를 사용하거나 업로드 중에 늘리십시오.

First 25 parts:   5MiB (total:  125MiB)
Next 25 parts:   10MiB (total:  375MiB)
Next 25 parts:   25MiB (total:    1GiB)
Next 25 parts:   50MiB (total: 2.25GiB)
After that:     100MiB

이를 통해 불필요한 메모리 낭비없이 최대 1TB (S3의 단일 파일에 대한 제한은 현재 5TB)의 파일을 업로드 할 수 있습니다.


Sean O'Donnells 블로그 링크 에 대한 참고 사항 :

그의 문제는 당신의 문제와 다릅니다. 그는 업로드하기 전에 Content-Length를 알고 사용합니다. 그는이 상황을 개선하기를 원합니다. 많은 라이브러리가 파일의 모든 데이터를 메모리로로드하여 업로드를 처리합니다. 의사 코드에서 다음과 같습니다.

data = File.read(file_name)
request = new S3::PutFileRequest()
request.setHeader('Content-Length', data.size)
request.setBody(data)
request.send()

그의 솔루션은 Content-Length파일 시스템 API를 통해 이를 수행합니다 . 그런 다음 디스크에서 요청 스트림으로 데이터를 스트리밍합니다. 의사 코드에서 :

upload = new S3::PutFileRequestStream()
upload.writeHeader('Content-Length', File.getSize(file_name))
upload.flushHeader()

input = File.open(file_name, File::READONLY_FLAG)

while (data = input.read())
  input.write(data)
end

upload.flush()
upload.close()

도움이 될 경우를 위해 다른 사람을 위해 여기에 답변을 넣으십시오.

S3까지 스트리밍하는 데이터의 길이를 모르는 경우 S3FileInfo및 그 OpenWrite()방법을 사용 하여 임의의 데이터를 S3에 쓸 수 있습니다 .

var fileInfo = new S3FileInfo(amazonS3Client, "MyBucket", "streamed-file.txt");

using (var outputStream = fileInfo.OpenWrite())
{
    using (var streamWriter = new StreamWriter(outputStream))
    {
        streamWriter.WriteLine("Hello world");
        // You can do as many writes as you want here
    }
}

gof3r 명령 줄 도구를 사용하여 Linux 파이프 만 스트리밍 할 수 있습니다 .

$ tar -czf - <my_dir/> | gof3r put --bucket <s3_bucket> --key <s3_object>

HTTP 다중 부분 항목 요청에 대해 자세히 알아보세요. 파일을 데이터 청크로 대상에 보낼 수 있습니다.


Node.js를 사용하는 경우 s3-streaming-upload 와 같은 플러그인 을 사용하여이 작업을 아주 쉽게 수행 할 수 있습니다.

참조 URL : https://stackoverflow.com/questions/8653146/can-i-stream-a-file-upload-to-s3-without-a-content-length-header

반응형