

# Amazon S3 제한 방지
<a name="performance-tuning-s3-throttling"></a>

제한은 서비스, 애플리케이션 또는 시스템 사용 속도를 제한하는 프로세스입니다. AWS에서는 제한을 사용하여 Amazon S3 서비스의 과도한 사용을 방지하고 모든 사용자에 대한 Amazon S3의 가용성과 응답성을 높일 수 있습니다. 그러나 제한 기능은 Amazon S3와의 데이터 전송 속도를 제한하므로 상호 작용이 제한되지 않도록 하는 것이 중요합니다.

[성능 조정](performance-tuning.md) 장에서 설명했듯이 최적화는 서비스 수준, 테이블 및 데이터 구조, 쿼리 작성 방법에 따라 달라질 수 있습니다.

**Topics**
+ [서비스 수준에서 제한 감소](performance-tuning-s3-throttling-reduce-throttling-at-the-service-level.md)
+ [테이블 최적화](performance-tuning-s3-throttling-optimizing-your-tables.md)
+ [쿼리 최적화](performance-tuning-s3-throttling-optimizing-queries.md)

# 서비스 수준에서 제한 감소
<a name="performance-tuning-s3-throttling-reduce-throttling-at-the-service-level"></a>

서비스 수준에서 Amazon S3 제한을 방지하려면 사용량을 모니터링하고 [서비스 할당량](https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3)을 조정하거나 파티셔닝과 같은 특정 기술을 사용할 수 있습니다. 다음은 제한으로 이어질 수 있는 몇 가지 조건입니다.
+ **계정의 API 요청 한도 초과** - Amazon S3에는 계정 유형 및 사용량에 따른 기본 API 요청 한도가 있습니다. 단일 접두사에 대한 초당 최대 요청 수를 초과하는 경우 Amazon S3 서비스의 과부하를 방지하기 위해 요청이 제한될 수 있습니다.
+ **불충분한 데이터 파티셔닝** -데이터를 적절하게 파티셔닝하지 않고 대량의 데이터를 전송하는 경우 Amazon S3에서 요청을 제한할 수 있습니다. 파티셔닝에 대한 자세한 내용은 이 문서의 [파티셔닝 사용](performance-tuning-s3-throttling-optimizing-your-tables.md#performance-tuning-s3-throttling-use-partitioning) 섹션을 참조하세요.
+ **많은 수의 작은 객체** - 가능하면 많은 수의 작은 파일을 만들지 않습니다. Amazon S3에는 파티셔닝된 접두사 1개에 대해 초당 [5,500개의 GET 요청](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) 한도가 있으며, Athena 쿼리는 이 한도를 공유합니다. 하나의 쿼리에서 수백만 개의 작은 객체를 스캔하는 경우 쿼리는 Amazon S3에 의해 제한될 수 있습니다.

과도한 스캔을 피하려면 AWS Glue ETL을 사용하여 파일을 주기적으로 압축하거나 테이블을 분할하고 파티션 키 필터를 추가하세요. 자세한 정보는 다음 리소스를 참조하세요.
+ [더 큰 파일을 출력하도록 AWS Glue ETL 작업을 구성하려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/glue-job-output-large-files/) (*AWS 지식 센터*)
+ [Reading input files in larger groups](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html)(*AWS Glue 개발자 안내서*)

# 테이블 최적화
<a name="performance-tuning-s3-throttling-optimizing-your-tables"></a>

제한 문제가 발생하는 경우 데이터를 구조화하는 것이 중요합니다. Amazon S3는 대량의 데이터를 처리할 수 있지만 데이터가 구조화되는 방식 때문에 때때로 제한이 발생합니다.

다음 섹션에서는 제한 문제를 방지하기 위해 Amazon S3에서 데이터를 구조화하는 방법에 대한 몇 가지 제안을 제공합니다.

## 파티셔닝 사용
<a name="performance-tuning-s3-throttling-use-partitioning"></a>

파티셔닝을 사용하면 언제든지 액세스해야 하는 데이터의 양을 제한하여 제한을 줄일 수 있습니다. 특정 열에서 데이터를 파티셔닝하면 요청을 여러 객체에서 고르게 분산하고 단일 객체에 대한 요청 수를 줄일 수 있습니다. 스캔해야 하는 데이터의 양을 줄이면 쿼리 성능이 향상되고 비용이 절감됩니다.

테이블을 생성할 때 가상 열 역할을 하는 파티션을 정의할 수 있습니다. `CREATE TABLE` 문에서 파티션이 있는 테이블을 생성하려면 `PARTITIONED BY (column_name data_type)` 절을 사용하여 데이터를 파티셔닝하는 키를 정의합니다.

쿼리에서 스캔하는 파티션을 제한하기 위해 쿼리의 `WHERE` 절에서 파티션을 조건자로 지정할 수 있습니다. 따라서 필터로 자주 사용되는 열이 파티셔닝에 적합합니다. 시간 간격에 따라 데이터를 파티셔닝하는 것이 일반적이며, 이때 여러 수준의 파티셔닝 체계가 형성될 수 있습니다.

파티셔닝에도 비용이 듭니다. 테이블에서 파티션 수를 늘리면 파티션 메타데이터를 검색하고 처리하는 데 필요한 시간도 늘어납니다. 따라서 과도하게 파티셔닝하면 보다 신중한 파티셔닝으로 얻을 수 있는 혜택이 사라질 수 있습니다. 데이터가 한 파티션 값으로 심하게 편중되고 대부분의 쿼리에서 이 값을 사용하는 경우 추가 오버헤드가 발생할 수 있습니다.

Athena에서 파티셔닝에 대한 자세한 내용은 [파티셔닝이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-partitioning.md) 섹션을 참조하세요.

## 데이터 버킷팅
<a name="performance-tuning-s3-throttling-bucket-your-data"></a>

데이터를 파티셔닝하는 또 다른 방법은 데이터를 단일 파티션 내에 버킷팅하는 것입니다. 버킷팅에서는 함께 그룹화하려는 행이 포함된 하나 이상의 열을 지정합니다. 그런 다음 해당 행을 여러 버킷에 넣습니다. 이 방식으로 읽어야 하는 버킷만 쿼리하여 스캔해야 하는 데이터 행 수를 줄일 수 있습니다.

버킷팅에 사용할 열을 선택하는 경우 카디널리티가 높고(즉, 개별 값이 많음) 균일하게 분산되었으며 데이터를 필터링하는 데 자주 사용되는 열을 선택합니다. 버킷팅에 사용하기에 좋은 열의 예로는 ID 열과 같은 기본 키가 있습니다.

Athena에서 버킷팅 사용에 대한 자세한 내용은 [버킷팅이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-bucketing.md) 섹션을 참조하세요.

## AWS Glue 파티션 인덱스 사용
<a name="performance-tuning-s3-throttling-use-aws-glue-partition-indexes"></a>

AWS Glue 파티션 인덱스를 사용하여 하나 이상의 파티션 값을 기반으로 테이블의 데이터를 구성할 수 있습니다. AWS Glue 파티션 인덱스를 사용하면 데이터 전송 횟수, 데이터 처리량, 쿼리 처리 시간을 줄일 수 있습니다.

AWS Glue 파티션 인덱스는 파티션 키 및 해당 값을 포함하여 테이블의 파티션에 대한 정보가 들어 있는 메타데이터 파일입니다. 파티션 인덱스는 Amazon S3 버킷에 저장되며 테이블에 새 파티션이 추가되면 AWS Glue에 의해 자동으로 업데이트됩니다.

AWS Glue 파티션 인덱스가 존재하면 테이블의 모든 파티션을 로드하는 대신 쿼리에서 파티션의 하위 세트를 가져오려고 합니다. 쿼리는 쿼리와 관련된 데이터의 하위 세트에서만 실행됩니다.

AWS Glue에서 테이블을 생성할 때 테이블에 정의된 파티션 키 조합에서 파티션 인덱스를 생성할 수 있습니다. 테이블에서 파티션 인덱스를 하나 이상 생성한 후에는 파티션 필터링을 활성화하는 속성을 테이블에 추가해야 합니다. 그런 다음 Athena에서 테이블을 쿼리할 수 있습니다.

AWS Glue에서 파티션 인덱스 생성에 대한 자세한 내용은 *AWS Glue 개발자 안내서*의 [Working with partition indexes in AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html)를 참조하세요. 파티션 필터링을 활성화하기 위해 테이블 속성을 추가하는 방법에 대한 자세한 내용은 [AWS Glue 파티션 인덱싱 및 필터링을 통한 쿼리 최적화](glue-best-practices-partition-index.md) 섹션을 참조하세요.

## 데이터 압축 및 파일 분할 사용
<a name="performance-tuning-s3-throttling-use-data-compression-and-file-splitting"></a>

파일이 최적 크기이거나 파일을 논리적 그룹으로 분할할 수 있는 경우 데이터 압축을 통해 쿼리 속도를 크게 높일 수 있습니다. 일반적으로 압축률이 높을수록 데이터를 압축하고 압축 해제하는 데 더 많은 CPU 사이클이 필요합니다. Athena의 경우 기본적으로 데이터를 압축하는 Apache Parquet 또는 Apache ORC를 사용하는 것이 좋습니다. Athena의 데이터 압축에 대한 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.

파일을 분할하면 Athena에서 단일 파일을 읽는 작업을 여러 리더에 분산시켜 병렬 처리 성능을 높일 수 있습니다. 단일 파일을 분할할 수 없는 경우 하나의 리더만 파일을 읽고 다른 리더가 유휴 상태로 둘 수 있습니다. Apache Parquet 및 Apache ORC도 분할 가능한 파일을 지원합니다.

## 최적화된 열 기반 데이터 스토어 사용
<a name="performance-tuning-s3-throttling-use-optimized-columnar-data-stores"></a>

데이터를 열 형식으로 변환하면 Athena 쿼리 성능이 크게 향상됩니다. 열 기반 파일을 생성할 때 고려할 한 가지 최적화 기법은 파티션 키를 기준으로 데이터를 정렬하는 것입니다.

Apache Parquet 및 Apache ORC는 흔히 사용되는 오픈 소스 열 기반 데이터 스토어입니다. 기존 Amazon S3 데이터 소스를 이러한 형식 중 하나로 변환하는 방법에 대한 자세한 내용은 [열 기반 형식으로 변환](columnar-storage.md#convert-to-columnar) 섹션을 참조하세요.

### 하나의 큰 Parquet 블록 크기 또는 ORC 스트라이프 크기 사용
<a name="performance-tuning-s3-throttling-use-a-larger-parquet-block-size-or-orc-stripe-size"></a>

Parquet 및 ORC에는 최적화를 위해 조정할 수 있는 데이터 스토리지 파라미터가 있습니다. Parquet에서는 블록 크기를 최적화할 수 있습니다. ORC에서는 스트라이프 크기를 최적화할 수 있습니다. 블록이나 스트라이프가 클수록 각 블록이나 스트라이프에 저장할 수 있는 행 수가 많아집니다. 기본적으로 Parquet 블록 크기는 128MB이고 ORC 스트라이프 크기는 64MB입니다.

ORC 스트라이프가 8MB(기본값 `hive.orc.max_buffer_size`) 미만인 경우 Athena는 전체 ORC 스트라이프를 읽습니다. 스트라이프 크기가 작은 경우 Athena는 초당 입력 및 출력 작업과 열 선택성 사이에서 이와 같이 절충합니다.

열 수가 매우 많은 테이블의 경우 블록 또는 스트라이프 크기가 작으면 필요 이상으로 많은 데이터가 스캔될 수 있습니다. 이 경우에는 블록 크기가 클수록 효율적입니다.

### 복잡한 유형에 대해 ORC 사용
<a name="performance-tuning-s3-throttling-use-orc-for-complex-types"></a>

현재 Parquet에 저장된 복잡한 데이터 형식(예: `array`, `map` 또는 `struct`)의 열을 쿼리하는 경우 Athena는 지정된 열만 선택적으로 읽는 대신, 전체 데이터 행을 읽습니다. 이것은 Athena에서 알려진 문제입니다. 이 문제를 해결하려면 ORC를 사용합니다.

### 압축 알고리즘 선택
<a name="performance-tuning-s3-throttling-choose-a-compression-algorithm"></a>

사용자가 구성할 수 있는 또 다른 파라미터는 데이터 블록의 압축 알고리즘입니다. Athena에서 Parquet 및 ORC용으로 지원되는 압축 알고리즘에 대한 자세한 내용은 [Athena 압축 지원](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html)을 참조하세요.

Athena에서 열 기반 스토리지 형식 최적화에 대한 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Top 10 Performance Tuning Tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)의 'Optimize columnar data store generation' 섹션을 참조하세요.

## Iceberg 테이블 사용
<a name="performance-tuning-s3-throttling-use-iceberg-tables"></a>

Apache Iceberg는 Amazon S3에서 최적화된 사용을 위해 설계된 초대형 분석 데이터 세트를 위한 오픈 테이블 형식입니다. Iceberg 테이블을 사용하면 Amazon S3에서 제한을 줄이는 데 도움이 될 수 있습니다.

Iceberg 테이블은 다음과 같은 이점을 제공합니다.
+ Iceberg 테이블은 하나 이상의 열로 분할할 수 있습니다. 이렇게 하면 데이터 액세스가 최적화되고 쿼리로 스캔해야 하는 데이터의 양이 줄어듭니다.
+ Iceberg 객체 스토리지 모드는 Amazon S3에서 사용할 수 있도록 Iceberg 테이블을 최적화하므로 대량의 데이터와 많은 쿼리 워크로드를 처리할 수 있습니다.
+ 객체 스토리지 모드의 Iceberg 테이블은 확장 가능하고 내결함성이 뛰어나며 내구성이 뛰어나므로 제한을 줄이는 데 도움이 될 수 있습니다.
+ ACID 트랜잭션 지원이란, 여러 사용자가 원자 단위로 Amazon S3 객체를 추가하고 삭제할 수 있음을 의미합니다.

Apache Iceberg에 대한 자세한 내용은 [Apache Iceberg](https://iceberg.apache.org/)를 참조하세요. Athena에서 Apache Iceberg 테이블 사용에 대한 자세한 내용은 [Iceberg 테이블 사용](https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg.html)을 참조하세요.

# 쿼리 최적화
<a name="performance-tuning-s3-throttling-optimizing-queries"></a>

Athena에서 SQL 쿼리를 최적화하려는 경우 이 섹션의 제안 사항을 사용합니다.

## ORDER BY 절과 함께 LIMIT 사용
<a name="performance-tuning-s3-throttling-use-limit-with-the-order-by-clause"></a>

`ORDER BY` 절은 정렬된 순서로 데이터를 반환합니다. 이를 위해 Athena에서 모든 데이터 행을 단일 워커 노드로 보낸 후 행을 정렬해야 합니다. 이러한 유형의 쿼리는 오래 실행되거나 실패할 수도 있습니다.

쿼리의 효율성을 높이려면 상위 또는 하위 *N*개 값을 확인하고 `LIMIT` 절도 사용합니다. 그러면 정렬과 제한을 단일 작업자가 아닌 개별 워커 노드로 푸시하여 정렬 비용을 크게 줄일 수 있습니다.

## JOIN 절 최적화
<a name="performance-tuning-s3-throttling-optimize-join-clauses"></a>

두 테이블을 조인하는 경우 Athena는 오른쪽에 있는 테이블을 워커 노드에 분산시킨 후 왼쪽의 테이블을 스트리밍하여 조인을 수행합니다.

따라서 조인 왼쪽에 큰 테이블을 지정하고 오른쪽에 작은 테이블을 지정합니다. 이렇게 하면 Athena는 메모리를 덜 사용하고 지연 시간을 줄이면서 쿼리를 실행합니다.

다음 사항에도 주의하세요.
+ 여러 `JOIN` 명령을 사용하는 경우 가장 큰 테이블부터 가장 작은 테이블의 순서로 지정합니다.
+ 쿼리에 필요하지 않는 한 크로스 조인을 사용하지 않습니다.

## GROUP BY 절 최적화
<a name="performance-tuning-s3-throttling-optimize-group-by-clauses"></a>

`GROUP BY` 연산자는 `GROUP BY` 열을 기반으로 워커 노드에 행을 분산시킵니다. 이러한 열은 메모리에서 참조되며 행을 모을 때 값이 비교됩니다. `GROUP BY` 열이 일치하면 값이 함께 집계됩니다. 이 프로세스의 작동 방식을 고려하면 카디널리티가 가장 높은 열부터 가장 낮은 열의 순서로 정렬하는 것이 좋습니다.

## 문자열 대신 숫자 사용
<a name="performance-tuning-s3-throttling-use-numbers-instead-of-strings"></a>

숫자는 문자열에 비해 메모리 사용량이 적고 처리 속도가 빠르므로 가능하면 문자열 대신 숫자를 사용합니다.

## 열 수 제한
<a name="performance-tuning-s3-throttling-limit-the-number-of-columns"></a>

데이터를 저장하는 데 필요한 총 메모리 양을 줄이려면 `SELECT` 문에 지정된 열 수를 제한합니다.

## LIKE 대신 정규식 사용
<a name="performance-tuning-s3-throttling-use-regular-expressions-instead-of-like"></a>

큰 문자열에서 `LIKE '%string%'`과 같은 절을 포함하는 쿼리는 컴퓨팅 집약적일 수 있습니다. 문자열 열에서 여러 값을 필터링하는 경우 대신 [regexp\$1like()](https://trino.io/docs/current/functions/regexp.html#regexp_like) 함수와 정규식을 사용합니다. 값의 긴 목록을 비교할 때 특히 유용합니다.

## LIMIT 절 사용
<a name="performance-tuning-s3-throttling-use-the-limit-clause"></a>

쿼리를 실행할 때 모든 열을 선택하는 대신 `LIMIT` 절을 사용하여 필요한 열만 반환합니다. 이렇게 하면 쿼리 실행 파이프라인을 통해 처리되는 데이터 세트의 크기가 줄어듭니다. `LIMIT` 절은 문자열 기반 열 수가 많은 테이블을 쿼리할 때 더 유용합니다. `LIMIT` 절은 쿼리에서 여러 조인 또는 집계를 수행할 때 유용합니다.