Amazon S3 성능 설계 패턴

Amazon S3 성능 설계 패턴

Amazon S3에서 객체를 업로드하고 가져오는 애플리케이션을 설계할 때는 애플리케이션의 최상의 성능을 얻기 위한 모범 사례 설계 패턴을 사용해요. 애플리케이션 아키텍처를 계획할 때 고려할 Amazon S3 성능 지침도 제공돼요.

출처: 문서

본문

성능을 최적화하려면 다음 설계 패턴을 사용할 수 있어요.

자주 접근하는 콘텐츠에 캐싱 사용 (Using caching for frequently accessed content)

Amazon S3에 데이터를 저장하는 많은 애플리케이션은 사용자가 반복적으로 요청하는 "작업 집합" 데이터를 제공해요. 워크로드가 공통 객체 집합에 반복 GET 요청을 보내는 경우 Amazon CloudFront나 Amazon ElastiCache 같은 캐시를 사용해 성능을 최적화할 수 있어요. 캐시를 성공적으로 도입하면 낮은 지연 시간과 높은 데이터 전송 속도를 얻을 수 있어요. 캐싱을 사용하는 애플리케이션은 Amazon S3에 보내는 직접 요청도 줄어들어 요청 비용을 낮추는 데 도움이 돼요.

Amazon CloudFront는 전 세계에 분산된 다수의 PoP(연결 지점)에서 Amazon S3의 데이터를 투명하게 캐시하는 빠른 콘텐츠 전송 네트워크(CDN)예요. 객체를 여러 리전에서 또는 인터넷을 통해 접근할 때, CloudFront는 데이터를 객체에 접근하는 사용자 가까이에 캐시할 수 있게 해줘요. 이는 인기 있는 Amazon S3 콘텐츠의 고성능 전달로 이어질 수 있어요. CloudFront에 대한 자세한 내용은 Amazon CloudFront Developer Guide를 참고하세요.

Amazon ElastiCache는 관리형 인메모리 캐시예요. ElastiCache로 객체를 메모리에 캐시하는 Amazon EC2 인스턴스를 프로비저닝할 수 있어요. 이 캐싱은 GET 지연 시간을 크기 정도(order of magnitude)로 줄이고 다운로드 처리량을 크게 높여요. ElastiCache를 사용하려면 애플리케이션 로직을 수정해 핫 객체로 캐시를 채우고, Amazon S3에서 객체를 요청하기 전에 캐시에 핫 객체가 있는지 확인해요. ElastiCache로 Amazon S3 GET 성능을 개선하는 예시는 블로그 게시물 Turbocharge Amazon S3 with Amazon ElastiCache for Redis를 참고하세요.

지연 시간에 민감한 애플리케이션의 타임아웃과 재시도 (Timeouts and retries for latency-sensitive applications)

애플리케이션이 Amazon S3로부터 재시도가 필요하다는 응답을 받는 상황이 있어요. Amazon S3는 버킷과 객체 이름을 그와 관련된 객체 데이터에 매핑해요. 애플리케이션이 높은 요청 빈도를 만들면(일반적으로 소수의 객체에 대해 초당 5,000건이 넘는 지속 요청률), HTTP 503 slowdown 응답을 받을 수 있어요. 이런 오류가 발생하면 각 AWS SDK는 지수 백오프를 사용한 자동 재시도 로직을 구현해요. AWS SDK를 사용하지 않는다면 HTTP 503 오류를 받을 때 재시도 로직을 직접 구현해야 해요. 백오프 기법에 대한 자세한 내용은 AWS SDKs and Tools Reference Guide의 재시도 동작을 참고하세요.

Amazon S3는 지속적인 새 요청률에 대응해 자동으로 확장되며 성능을 동적으로 최적화해요. Amazon S3가 내부적으로 새 요청률에 맞춰 최적화하는 동안에는 최적화가 완료될 때까지 일시적으로 HTTP 503 요청 응답을 받게 돼요. Amazon S3가 새 요청률에 맞춰 내부적으로 성능을 최적화한 뒤에는 일반적으로 모든 요청이 재시도 없이 처리돼요.

지연 시간에 민감한 애플리케이션의 경우 Amazon S3는 느린 작업을 추적하고 적극적으로 재시도할 것을 권장해요. 요청을 재시도할 때는 Amazon S3에 새 연결을 사용하고 새 DNS 조회를 수행할 것을 권장해요.

크기가 크고 다양한 요청(예: 128MB 초과)을 보낼 때는 달성 중인 처리량을 추적하고 가장 느린 5%의 요청을 재시도할 것을 권장해요. 더 작은 요청(예: 512KB 미만)을 보낼 때는 중앙값 지연 시간이 수십 밀리초 범위인 경우가 많으므로, 2초 후 GET 또는 PUT 작업을 재시도하는 것이 좋은 지침이에요. 추가 재시도가 필요하다면 백오프하는 것이 모범 사례예요. 예를 들어 2초 후 한 번 재시도하고, 추가 4초 후 두 번째 재시도를 권장해요.

애플리케이션이 Amazon S3에 고정 크기 요청을 보낸다면 각 요청의 응답 시간이 더 일관적일 것으로 기대해야 해요. 이 경우 가장 느린 1%의 요청을 식별해 재시도하는 간단한 전략을 사용하면 돼요. 한 번의 재시도만으로도 지연 시간을 줄이는 데 자주 효과적이에요.

서버 측 암호화에 AWS Key Management Service(AWS KMS)를 사용한다면, 사용 사례에서 지원되는 요청 빈도에 대한 정보는 AWS Key Management Service Developer Guide의 Quotas를 참고하세요.

높은 처리량을 위한 수평 확장과 요청 병렬화 (Horizontal scaling and request parallelization for high throughput)

Amazon S3는 매우 큰 분산 시스템이에요. 그 규모를 활용하려면 Amazon S3 서비스 엔드포인트에 대한 병렬 요청을 수평으로 확장할 것을 권장해요. 이런 확장 방식은 요청을 Amazon S3 안에서 분산시킬 뿐 아니라 네트워크의 여러 경로에 부하를 분산시키는 데도 도움이 돼요.

높은 처리량 전송을 위해 Amazon S3는 데이터를 병렬로 GET 또는 PUT하는 여러 연결을 사용하는 애플리케이션을 권장해요. 예를 들어 AWS Java SDK의 Amazon S3 Transfer Manager가 이를 지원하며, 대부분의 다른 AWS SDK도 비슷한 구조를 제공해요. 일부 애플리케이션에서는 서로 다른 애플리케이션 스레드나 서로 다른 애플리케이션 인스턴스에서 여러 요청을 동시에 실행해 병렬 연결을 이룰 수 있어요. 어떤 접근 방식이 최선인지는 애플리케이션과 접근하는 객체의 구조에 따라 달라져요.

AWS SDK를 사용해 전송 관리를 이용하기보다 GET과 PUT 요청을 직접 보낼 수도 있어요. 이 방식은 SDK의 재시도 지원과 HTTP 503 응답 처리의 혜택을 누리면서도 워크로드를 더 직접 조정할 수 있게 해줘요. 일반적으로 Amazon S3에서 큰 객체를 다운로드할 때는 네트워크 처리량을 최대화하고 다운로드 성능을 최적화하기 위해 동시 요청을 하는 것을 권장해요. 객체의 특정 바이트 범위를 요청하거나 멀티파트 객체의 개별 파트를 동시에 다운로드하는 방식으로 이를 달성할 수 있어요. 이 병렬 다운로드 방식은 네트워크 인터페이스 카드(NIC) 용량을 완전히 활용하는 데 도움이 돼요. 멀티파트 업로드로 업로드된 객체는 최상의 성능을 위해 같은 파트 크기로 다운로드하거나 원래 파트 경계에 맞춰 요청하는 것을 권장해요. 이 동시 다운로드 방식은 단일 전체 객체 요청보다 더 높은 집계 처리량을 제공해요.

동시에 보낼 요청 수를 조정할 때는 성능 측정이 중요해요. 한 번에 단일 요청으로 시작할 것을 권장해요. 달성 중인 네트워크 대역폭과 애플리케이션이 데이터를 처리할 때 사용하는 다른 리소스를 측정해요. 그러면 병목 리소스(즉, 사용량이 가장 높은 리소스)를 식별할 수 있고, 따라서 유용할 가능성이 있는 요청 수를 알 수 있어요. 예를 들어 한 번에 하나의 요청을 처리할 때 CPU 사용량이 25%라면 최대 4개의 동시 요청을 수용할 수 있음을 시사해요. 측정은 필수이며, 요청률을 높일 때 리소스 사용을 확인해 볼 가치가 있어요.

애플리케이션이 REST API로 Amazon S3에 직접 요청을 보낸다면 HTTP 연결 풀을 사용하고 일련의 요청에 각 연결을 재사용할 것을 권장해요. 요청별 연결 설정을 피하면 각 요청에서 TCP 슬로우 스타트와 SSL(보안 소켓 계층) 핸드셰이크를 수행할 필요가 없어져요. REST API 사용에 대한 자세한 내용은 Amazon Simple Storage Service API Reference를 참고하세요.

마지막으로 DNS에 주의를 기울여 요청이 넓은 Amazon S3 IP 주소 풀에 분산되는지 다시 확인할 가치가 있어요. Amazon S3에 대한 DNS 쿼리는 많은 IP 엔드포인트 목록을 순환해요. 하지만 캐싱 리졸버나 단일 IP 주소를 재사용하는 애플리케이션 코드는 주소 다양성과 그에 따른 로드 밸런싱의 혜택을 누리지 못해요. netstat 같은 네트워크 유틸리티 도구가 Amazon S3와의 통신에 사용되는 IP 주소를 보여줄 수 있으며, 사용할 DNS 구성에 대한 지침도 제공돼요. 이 지침에 대한 자세한 내용은 Amazon S3 API Reference의 Making requests를 참고하세요.

지리적으로 분산된 데이터 전송 가속화에 Amazon S3 Transfer Acceleration 사용 (Using Amazon S3 Transfer Acceleration to accelerate geographically disparate data transfers)

Amazon S3 Transfer Acceleration으로 빠르고 안전한 파일 전송 구성은 전 세계에 분산된 클라이언트와 Amazon S3를 사용하는 리전별 애플리케이션 사이의 지리적 거리로 인한 지연 시간을 최소화하거나 제거하는 데 효과적이에요. Transfer Acceleration은 데이터 전송에 CloudFront의 전 세계 분산 에지 위치를 사용해요. AWS 에지 네트워크는 50개 이상의 위치에 연결 지점(PoP)이 있어요. 오늘날에는 CloudFront를 통해 콘텐츠를 배포하고 Amazon Route 53에 대한 DNS 쿼리에 빠르게 응답하는 데 사용돼요.

에지 네트워크는 Amazon S3로 들어오고 나가는 데이터 전송도 가속화하는 데 도움이 돼요. 대륙을 가로지르거나 대륙 간에 데이터를 전송하고, 빠른 인터넷 연결을 사용하며, 큰 객체를 사용하거나, 업로드할 콘텐츠가 많은 애플리케이션에 이상적이에요. 데이터가 에지 위치에 도착하면 최적화된 네트워크 경로를 통해 Amazon S3로 라우팅돼요. 일반적으로 Amazon S3 리전에서 멀어질수록 Transfer Acceleration을 사용해 기대할 수 있는 속도 개선이 더 커요.

Transfer Acceleration은 새 버킷이나 기존 버킷에서 설정할 수 있어요. 별도의 Amazon S3 Transfer Acceleration 엔드포인트를 사용해 AWS 에지 위치를 활용할 수 있어요. Transfer Acceleration이 클라이언트 요청 성능에 도움이 되는지 테스트하는 가장 좋은 방법은 Amazon S3 Transfer Acceleration Speed Comparison 도구를 사용하는 것이에요. 네트워크 구성과 조건은 시간과 위치에 따라 달라져요. 그래서 Amazon S3 Transfer Acceleration이 업로드 성능을 잠재적으로 개선할 수 있는 전송에 대해서만 요금이 부과돼요. 다양한 AWS SDK로 Transfer Acceleration을 사용하는 방법은 S3 Transfer Acceleration 활성화 및 사용을 참고하세요.

높은 요청 빈도 워크로드에 맞춘 최적화 (Optimizing for high-request rate workloads)

Amazon S3에 높은 요청 빈도를 만드는 애플리케이션은 최적의 성능을 달성하기 위해 특정 설계 패턴이 필요해요. 애플리케이션이 접두사당 초당 3,500건 이상의 PUT/COPY/POST/DELETE 또는 5,500건 이상의 GET/HEAD 요청을 지속적으로 발생시키면, 요청을 분산하고 확장 동작을 처리하는 전략을 구현해야 해요.

Amazon S3는 더 높은 요청 빈도를 수용하도록 자동으로 확장하지만, 이 확장은 점진적으로 이루어져요. 확장 과정에서 HTTP 503(Slow Down) 응답을 받을 수 있어요. 이런 응답은 일시적이며, Amazon S3가 새 요청 패턴에 맞춰 내부 시스템을 최적화하고 있음을 나타내요. 확장이 완료되면 요청은 제한 없이 처리돼요.

높은 요청 빈도 워크로드의 성능을 최적화하려면 다음 전략을 고려해요.

  • 여러 접두사에 요청 분산 – 무작위 또는 순차 접두사 패턴을 사용해 여러 파티션에 요청을 분산해요. 예를 들어 log-2024-01-01.txt 같은 순차 객체 이름 대신 a1b2/log-2024-01-01.txt 같은 무작위 접두사를 사용해요. 이렇게 하면 Amazon S3가 부하를 더 효과적으로 분산하는 데 도움이 돼요.
  • 503 오류에 지수 백오프 구현 – HTTP 503 응답을 받으면 지수 백오프가 있는 재시도 로직을 구현해요. 짧은 지연으로 시작하고 재시도 간 대기 시간을 점진적으로 늘려요. AWS SDK에는 이를 자동으로 처리하는 내장 재시도 로직이 포함되어 있어요.
  • 요청 패턴 모니터링 – Amazon CloudWatch 지표로 요청률과 오류율을 모니터링해요. 특히 5xx 오류 지표에 주의를 기울이세요. 애플리케이션이 현재 확장 한도에 근접하거나 초과하고 있음을 나타낼 수 있어요.
  • 요청률을 점진적으로 높이기 – 새 애플리케이션을 시작하거나 요청률을 크게 높일 때는 즉시 피크 속도로 뛰기보다 시간에 따라 트래픽을 점진적으로 늘려요. 이렇게 하면 Amazon S3가 선제적으로 확장할 수 있고 제한 가능성이 줄어들어요.
  • 여러 연결 사용 – 여러 HTTP 연결에 요청을 분산해 처리량을 최대화하고 단일 연결 문제의 영향을 줄여요.

일관된 고성능이 필요한 애플리케이션은 단일 자릿수 밀리초 지연 시간을 요구하고 초당 수십만 건의 요청을 지원할 수 있도록 설계된 Amazon S3 Express One Zone을 고려해요. 자세한 내용은 S3 Express One Zone을 참고하세요.

더 알아보기 (Learn more)