Facts
✅ S3를 이용한 사진 업로드 기능 속도 개선
Findings
문제점
프로젝트를 Flask/Python → Spring/Java로 바꿔주면서,
S3와 CloudFront를 이용한 사진 업로드 API 호출 속도가 느려졌다. 🐢 💦
문제 원인
문제의 원인을 파악해보자.
S3 이미지 업로드 기능을 위한 Python의 라이브러리는 Boto3를 사용해주었다.
Spring으로 바꾸면서, S3 이미지 업로드 기능을 위한 Java의 라이브러리는 amazonS3.putObject()가 있어
이것으로 변경해주었다.
🤔 둘의 라이브러리의 속도 차이가 왜 날까?
멀티 스레딩 기술의 유무 차이로 추측이 되는데, 둘의 라이브러리의 내부 원리를 찾아보자.
1️⃣ Python의 Boto3
Boto3의 공식문서를 보면, S3로 이미지 업로드 할 때, 동시성의 원리로 파일을 업로드 해준다고 한다.
Boto3의 내부 코드를 보면, 동시성으로 구현한 것을 확인해줄 수가 있다.
2️⃣ Java의 amazonS3.putObject
amazonS3.putObject()의 경우, 업로드할 객체를 쓰라고 여러번 요청받지만,
맨마지막으로 작성한 객체가 최종적으로 덮어 씌워진다고 한다.
해결책
S3 이미지 업로드 기능을 위한 Java 라이브러리 중 멀티스레딩을 사용하는 기술이 없을까?
멀티스레딩 기술 외에도 속도를 개선할 방법이 무엇이 있을까?
생각해보며, AWS SDK for Java 공식 문서를 찾아보았다.
MultiPart 파일을 안정적으로 전송할 수 있고 전송의 예외처리 할수 있는 TransferManager 라이브러리 발견했다.
TransferManager 라이브러리는 multiple threads를 사용하여, MultiPart 파일을 업로드 한다고 한다.
TransferManager를 사용하여 이미지 업로드 함수를 호출하여, 이미지 업로드 변경 속도 상승시켰다.
기존에는 업데이트 속도 5000ms였는데, 1000ms이내로 변경이 되었다. 🚀
변경전 코드
@Component
@RequiredArgsConstructor
public class AwsS3Service {
private final AmazonS3 amazonS3;
private final S3Component s3component;
...
public void uploadFile(InputStream inputStream, ObjectMetadata objectMetadata, String fileName) {
amazonS3.putObject(new PutObjectRequest(s3component.getBucket(), fileName, inputStream, objectMetadata).withCannedAcl(CannedAccessControlList.PublicReadWrite));
}
}
변경후 코드
private final AmazonS3Client amazonS3Client;
...
private void uploadOnS3(String findName, InputStream inputStream, ObjectMetadata objectMetadata) {
TransferManager transferManager = TransferManagerBuilder.standard().withS3Client(amazonS3Client).build();
PutObjectRequest request = new PutObjectRequest(bucket, findName, inputStream, objectMetadata).withCannedAcl(CannedAccessControlList.PublicRead);
Upload upload = transferManager.upload(request);
try {
upload.waitForCompletion();
} catch (AmazonClientException amazonClientException) {
log.error(amazonClientException.getMessage());
} catch (InterruptedException e) {
log.error(e.getMessage());
}
}
참고 자료
'Project > TIL, WIL' 카테고리의 다른 글
TIL(52) Elasticbeanstalk에 HTTPS를 연결 (0) | 2021.12.27 |
---|---|
TIL(51) JPA 관련 에러 고치기 (0) | 2021.12.27 |
TIL(49) 21-12-09: CORS 에러 해결하기 (0) | 2021.12.27 |
TIL(48) 21-12-08: API 문서 자동화와 테스트 코드 작성하기 (Using RestDoc) (0) | 2021.12.27 |
TIL(47) 21-12-07: ElasticBeanstalk으로 백엔드 아키텍처 구성하고 GithubAction으로 프로젝트 배포 (0) | 2021.12.27 |