

# AWS Glue ETL에서 푸시다운을 사용한 읽기 최적화
<a name="aws-glue-programming-pushdown"></a>

 푸시다운은 데이터 검색에 대한 로직을 데이터 소스에 더 가깝게 푸시하는 최적화 기법입니다. 소스는 Amazon S3와 같은 파일 시스템 또는 데이터베이스일 수 있습니다. 소스에서 직접 특정 작업을 실행하는 경우 네트워크를 통해 AWS Glue에서 관리하는 Spark 엔진으로 모든 데이터를 가져오지 않아도 되므로 시간과 처리 용량을 절감할 수 있습니다.

이를 다른 방법으로 설명하자면 푸시다운이 데이터 스캔을 줄이는 것입니다. 이 기법이 적절한 시기를 식별하는 프로세스에 대한 자세한 내용은 AWS 권장 가이드의 *Apache Spark용 AWS Glue 작업 성능 조정 모범 사례* 가이드에 있는 [데이터 스캔량 감소](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/reduce-data-scan.html)를 참조하세요.

## Amazon S3에 저장된 파일에서 조건자 푸시다운
<a name="aws-glue-programming-pushdown-s3"></a>

 Amazon S3에서 접두사를 기준으로 구성된 파일을 사용하는 경우 푸시다운 조건자를 정의하여 대상 Amazon S3 경로를 필터링할 수 있습니다. 전체 데이터 세트를 읽고 `DynamicFrame` 내에서 필터를 적용하는 대신 AWS Glue 데이터 카탈로그에 저장된 파티션 메타데이터에 필터를 직접 적용할 수 있습니다. 이 방법을 사용하면 필요한 데이터만 선택적으로 나열하고 읽을 수 있습니다. 파티션별 버킷 쓰기를 포함하여 이 프로세스에 대한 자세한 내용은 [AWS Glue에서 ETL 출력의 파티션 관리](aws-glue-programming-etl-partitions.md) 섹션을 참조하세요.

Amazon S3에서 `push_down_predicate` 파라미터를 사용하여 조건부 푸시다운을 수행합니다. Amazon S3의 버킷을 연도, 월, 일을 기준으로 파티셔닝했다고 가정합니다. 2022년 6월의 고객 데이터를 검색하려는 경우 관련 Amazon S3 경로만 읽도록 AWS Glue에 지시할 수 있습니다. 이 경우 `push_down_predicate`는 `year='2022' and month='06'`입니다. 따라서 다음과 같이 읽기 작업을 수행할 수 있습니다.

------
#### [ Python ]

```
customer_records = glueContext.create_dynamic_frame.from_catalog( 
    database = "customer_db", 
    table_name = "customer_tbl",
    push_down_predicate = "year='2022' and month='06'"
)
```

------
#### [ Scala ]

```
val customer_records = glueContext.getCatalogSource(
database="customer_db", 
tableName="customer_tbl", 
pushDownPredicate="year='2022' and month='06'"
).getDynamicFrame()
```

------

이전 시나리오에서 `push_down_predicate`는 AWS Glue 데이터 카탈로그의 모든 파티션 목록을 검색하고 기본 Amazon S3 파일을 읽기 전에 파티션을 필터링합니다. 대부분의 경우 이 방법이 유용하지만 수백만 개의 파티션이 있는 데이터 세트를 작업할 때는 파티션을 나열하는 데 시간이 많이 걸릴 수 있습니다. 이 문제를 해결하기 위해 서버 측 파티션 정리를 사용하여 성능을 개선할 수 있습니다. AWS Glue 데이터 카탈로그에서 데이터에 대한 **파티션 인덱스**를 구축하면 됩니다. 파티션 인덱스에 대한 자세한 내용은 [파티션 인덱스 생성](partition-indexes.md) 섹션을 참조하세요. 그런 다음 `catalogPartitionPredicate` 옵션을 사용하여 인덱스를 참조할 수 있습니다. `catalogPartitionPredicate`를 사용하여 파티션을 검색하는 예제는 [카탈로그 파티션 조건자를 사용한 서버 측 필터링](aws-glue-programming-etl-partitions.md#aws-glue-programming-etl-partitions-cat-predicates) 섹션을 참조하세요.

## JDBC 소스를 사용할 때 푸시다운
<a name="aws-glue-programming-pushdown-jdbc"></a>

`GlueContext`에서 사용되는 AWS Glue JDBC 리더는 소스에서 직접 실행할 수 있는 사용자 지정 SQL 쿼리를 제공하여 지원되는 데이터베이스에서의 푸시다운을 지원합니다. `sampleQuery` 파라미터를 설정하여 이 작업을 수행할 수 있습니다. 샘플 쿼리는 선택할 열을 지정할 수 있을 뿐만 아니라 Spark 엔진으로 전송되는 데이터를 제한하는 푸시다운 조건자를 제공할 수 있습니다.

기본적으로 샘플 쿼리는 단일 노드에서 작동하므로 대량의 데이터를 처리할 때 작업에 실패할 수 있습니다. 이 기능을 사용하여 대규모로 데이터를 쿼리하려면 `enablePartitioningForSampleQuery`를 true로 설정하여 쿼리 파티셔닝을 구성해야 합니다. 그러면 선택한 키의 여러 노드에 쿼리가 배포됩니다. 쿼리 파티셔닝에는 몇 가지 다른 필수 구성 파라미터도 필요합니다. 쿼리 파티셔닝에 대한 자세한 내용은 [JDBC 테이블을 병렬로 읽기](run-jdbc-parallel-read-job.md) 섹션을 참조하세요.

`enablePartitioningForSampleQuery`를 설정하면 AWS Glue는 데이터베이스를 쿼리할 때 푸시다운 조건자를 파티셔닝 조건자와 결합합니다. AWS Glue에서 파티션 조건을 추가하려면 `sampleQuery`는 `AND`로 끝나야 합니다. (푸시다운 조건자를 제공하지 않는 경우 `sampleQuery`는 `WHERE`로 끝나야 합니다.) `id`가 1,000보다 큰 행만 검색하도록 조건자를 푸시하는 아래 예제를 참조하세요. 이 `sampleQuery`에서는 `id`가 지정된 값보다 큰 행의 이름 및 위치 열만 반환합니다.

------
#### [ Python ]

```
sample_query = "select name, location from customer_tbl WHERE id>=1000 AND"
customer_records = glueContext.create_dynamic_frame.from_catalog(
    database="customer_db",
    table_name="customer_tbl",
    sample_query = "select name, location from customer_tbl WHERE id>=1000 AND",

    additional_options = { 
                           "hashpartitions": 36 , 
                           "hashfield":"id",
                           "enablePartitioningForSampleQuery":True, 
                           "sampleQuery":sample_query
                          }
)
```

------
#### [ Scala ]

```
val additionalOptions = Map( 
        "hashpartitions" -> "36", 
        "hashfield" -> "id", 
        "enablePartitioningForSampleQuery" -> "true", 
        "sampleQuery" -> "select name, location from customer_tbl WHERE id >= 1000 AND"
        )
 
    val customer_records = glueContext.getCatalogSource(
        database="customer_db", 
        tableName="customer_tbl").getDynamicFrame()
```

------

**참고**  
`customer_tbl`이 데이터 카탈로그와 기초 데이터 스토어의 이름이 다른 경우 쿼리가 기초 데이터 스토어로 전달되므로 sample\$1query에 기초 테이블 이름을 제공해야 합니다.

AWS Glue 데이터 카탈로그와 통합하지 않고도 JDBC 테이블을 쿼리할 수도 있습니다. 사용자 이름과 암호를 메서드의 파라미터로 제공하는 대신 `useConnectionProperties` 및 `connectionName`을 제공하여 기존 연결의 보안 인증을 재사용할 수 있습니다. 이 예제에서는 `my_postgre_connection`이라는 연결에서 보안 인증을 검색합니다.

------
#### [ Python ]

```
connection_options_dict = {
    "useConnectionProperties": True,
    "connectionName": "my_postgre_connection",
    "dbtable":"customer_tbl",
    "sampleQuery":"select name, location from customer_tbl WHERE id>=1000 AND",
    "enablePartitioningForSampleQuery":True,
    "hashfield":"id",
    "hashpartitions":36
    }

customer_records = glueContext.create_dynamic_frame.from_options(
    connection_type="postgresql",
    connection_options=connection_options_dict
    )
```

------
#### [ Scala ]

```
val connectionOptionsJson = """
      {
        "useConnectionProperties": true,
        "connectionName": "my_postgre_connection",
        "dbtable": "customer_tbl",
        "sampleQuery": "select name, location from customer_tbl WHERE id>=1000 AND",
        "enablePartitioningForSampleQuery" : true,
        "hashfield" : "id",
        "hashpartitions" : 36
      }
    """
    
    val connectionOptions = new JsonOptions(connectionOptionsJson)
    
    val dyf = glueContext.getSource("postgresql", connectionOptions).getDynamicFrame()
```

------

## AWS Glue에서 푸시다운에 대한 참고 및 제한 사항
<a name="aws-glue-programming-pushdown-other"></a>

푸시다운은 개념상 비스트리밍 소스(AWS)에서 읽을 때 적용됩니다. Glue는 다양한 소스를 지원하며, 푸시다운 기능은 소스와 커넥터에 따라 다릅니다.
+ Snowflake에 연결할 때는 `query` 옵션을 사용할 수 있습니다. AWS Glue 4.0 이상 버전의 Redshift 커넥터에도 비슷한 기능이 있습니다. `query`를 사용하여 Snowflake에서 읽는 방법에 대한 자세한 내용은 [Snowflake 테이블에서 읽기](aws-glue-programming-etl-connect-snowflake-home.md#aws-glue-programming-etl-connect-snowflake-read) 섹션을 참조하세요.
+ DynamoDB ETL 리더는 필터 또는 푸시다운 조건자를 지원하지 않습니다. MongoDB 및 DocumentDB도 이러한 종류의 기능을 지원하지 않습니다.
+ Amazon S3에서 오픈 테이블 형식으로 저장된 데이터를 읽을 때는 Amazon S3에 있는 파일을 파티셔닝하는 방법이 더 이상 적합하지 않습니다. 오픈 테이블 형식을 사용하여 파티션에서 읽고 쓰려면 해당 형식에 대한 설명서를 참조하세요.
+ DynamicFrame 메서드는 Amazon S3 프로젝션 푸시다운을 수행하지 않습니다. 조건자 필터를 통과한 파일에서 모든 열을 읽습니다.
+ AWS Glue에서 `custom.jdbc` 커넥터를 사용할 때 푸시다운 기능은 소스와 커넥터에 따라 달라집니다. 해당 커넥터 설명서를 검토하여 AWS Glue에서 푸시다운을 지원하는지 여부와 지원 방법을 확인하세요.