개발자로서 우리는 대규모 데이터 처리 및 전달을 처리할 때 종종 어려움에 직면합니다. Kamero에서는 최근 파일 전송 파이프라인의 심각한 병목 현상을 해결했습니다. 우리 애플리케이션을 사용하면 사용자는 특정 이벤트와 관련된 수천 개의 파일을 단일 zip 파일로 다운로드할 수 있습니다. S3 버킷에서 파일을 가져오고 압축하는 역할을 하는 Node.js 기반 Lambda 함수로 구동되는 이 기능은 사용자 기반이 증가함에 따라 메모리 제약과 긴 실행 시간으로 인해 어려움을 겪고 있었습니다.
이 게시물에서는 리소스가 부족한 Node.js 구현에서 대규모 S3 다운로드를 효율적으로 처리하는 간결하고 초고속 Go 솔루션으로의 여정을 자세히 설명합니다. 특정 이벤트에서 대량의 파일을 요청할 때 사용자에게 원활한 환경을 제공하기 위해 시스템을 최적화한 방법을 살펴보겠습니다. 이 모든 파일은 모두 편리한 단일 zip 다운로드로 패키지되어 있습니다.
저희 원래 Lambda 함수는 대규모 이벤트 기반 파일 세트를 처리할 때 몇 가지 중요한 문제에 직면했습니다.
원래 구현에서는 s3-zip 라이브러리를 사용하여 S3 객체에서 zip 파일을 생성했습니다. 다음은 파일 처리 방법에 대한 간단한 정보입니다.
const s3Zip = require("s3-zip"); // ... other code ... const body = s3Zip.archive( { bucket: bucketName }, eventId, files, entryData ); await uploadZipFile(Upload_Bucket, zipfileKey, body);
이 접근 방식은 효과가 있었지만 zip을 생성하기 전에 모든 파일을 메모리에 로드하여 메모리 사용량이 늘어나고 대용량 파일 세트의 경우 메모리 부족 오류가 발생할 수 있습니다.
우리는 효율성과 내장된 동시성 기능을 활용하여 Go에서 Lambda 함수를 다시 작성하기로 결정했습니다. 결과는 놀라웠습니다.
우리는 v1에 비해 더 나은 성능과 더 낮은 메모리 사용량을 제공하는 Go v2용 AWS SDK를 사용했습니다.
cfg, err := config.LoadDefaultConfig(context.TODO()) s3Client = s3.NewFromConfig(cfg)
Go의 고루틴을 사용하면 여러 파일을 동시에 처리할 수 있습니다.
var wg sync.WaitGroup sem := make(chan struct{}, 10) // Limit concurrent operations for _, photo := range photos { wg.Add(1) go func(photo Photo) { defer wg.Done() sem <- struct{}{} // Acquire semaphore defer func() { <-sem }() // Release semaphore // Process photo }(photo) } wg.Wait()
이 접근 방식을 사용하면 동시성 수준을 제어하여 시스템에 부담을 주지 않고 여러 파일을 동시에 처리할 수 있습니다.
모든 파일을 메모리에 로드하는 대신 zip 콘텐츠를 S3에 직접 스트리밍합니다.
pipeReader, pipeWriter := io.Pipe() go func() { zipWriter := zip.NewWriter(pipeWriter) // Add files to zip zipWriter.Close() pipeWriter.Close() }() // Upload streaming content to S3 uploader.Upload(ctx, &s3.PutObjectInput{ Bucket: &destBucket, Key: &zipFileKey, Body: pipeReader, })
이 스트리밍 접근 방식을 사용하면 메모리 사용량이 크게 줄어들고 훨씬 더 큰 파일 세트를 처리할 수 있습니다.
Go를 다시 작성하여 인상적인 개선이 이루어졌습니다.
Go에서 Lambda 기능을 다시 작성하면 즉각적인 확장 문제가 해결되었을 뿐만 아니라 파일 처리 요구 사항에 맞는 더욱 강력하고 효율적인 솔루션이 제공되었습니다. 처음에는 Node.js가 우리에게 큰 도움이 되었지만 이번 경험을 통해 특히 규모에 맞게 리소스 집약적인 작업을 처리할 때 작업에 적합한 도구를 선택하는 것이 중요하다는 점을 강조했습니다.
가장 적합한 언어나 프레임워크는 특정 사용 사례에 따라 다르다는 점을 기억하세요. 우리 시나리오에서 Go의 성능 특성은 우리의 요구 사항과 완벽하게 일치하여 사용자 경험이 크게 향상되고 운영 비용이 절감되었습니다.
서버리스 기능과 관련해 비슷한 문제에 직면한 적이 있나요? 어떻게 극복하셨나요? 아래 댓글을 통해 귀하의 경험을 듣고 싶습니다!
위 내용은 Node.js에서 Go까지: 단일 Zip으로 수천 개의 파일 다운로드 슈퍼차저의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!