

# AWS Glue for Spark에서 입력 및 출력의 데이터 형식 옵션
<a name="aws-glue-programming-etl-format"></a>

이 페이지는 AWS Glue for Spark에서 지원하는 데이터 형식에 대한 기능 지원 및 구성 파라미터에 대한 정보를 제공합니다. 이 정보의 사용 및 적용 가능성에 대한 설명은 다음을 참조하세요.

## AWS Glue의 데이터 형식 전반에 걸친 기능 지원
<a name="aws-glue-programming-etl-format-features"></a>

 각 데이터 형식은 다른 AWS Glue 기능을 지원할 수 있습니다. 다음 공통 기능은 해당 형식 유형에 따라 지원되거나 지원되지 않을 수 있습니다. 요구 사항을 충족하기 위해 기능을 활용하는 방법을 이해하려면 데이터 형식에 대한 설명서를 참조하세요.


|  |  | 
| --- |--- |
| 읽기 | AWS Glue는 커넥터와 같은 추가 리소스 없이 이 데이터 형식을 인식하고 해석할 수 있습니다. | 
| 쓰기 | AWS Glue는 추가 리소스 없이 이 형식으로 데이터를 쓸 수 있습니다. 다른 Spark 환경에서와 같이 작업에 타사 라이브러리를 포함하고 표준 Apache Spark 기능을 사용하여 데이터를 작성할 수 있습니다. 라이브러리를 포함한 자세한 내용은 [AWS Glue와 함께 Python 라이브러리 사용](aws-glue-programming-python-libraries.md) 단원을 참조하세요. | 
| 스트리밍 읽기 | AWS Glue는 Apache Kafka, Amazon Managed Streaming for Apache Kafka 또는 Amazon Kinesis 메시지 스트림에서 이 데이터 형식을 인식하고 해석할 수 있습니다. 스트림이 일관된 형식으로 데이터를 표시할 것으로 예상하므로 DataFrames로 읽습니다. | 
| 작은 파일 그룹화 | AWS Glue는 AWS Glue 변환을 수행할 때 각 노드로 전송되는 일괄 작업으로 파일을 그룹화할 수 있습니다. 이렇게 하면 많은 양의 작은 파일이 포함된 워크로드의 성능이 크게 향상될 수 있습니다. 자세한 내용은 [입력 파일을 더 큰 그룹에서 읽기](grouping-input-files.md) 섹션을 참조하세요. | 
| 작업 북마크 | AWS Glue는 작업 북마크를 사용하여 작업 실행 전반에 걸쳐 동일한 데이터 세트에서 동일한 작업을 수행하는 변환의 진행 상황을 추적할 수 있습니다. 이렇게 하면 마지막 작업 실행 이후 새 데이터에 대해서만 작업을 수행해야 하는 데이터 세트와 관련된 워크로드의 성능을 향상시킬 수 있습니다. 자세한 내용은 [처리된 데이터를 작업 북마크로 추적](monitor-continuations.md) 섹션을 참조하세요. | 

## AWS Glue의 데이터 형식과 상호 작용하는 데 사용되는 파라미터
<a name="aws-glue-programming-etl-format-parameters"></a>

특정 AWS Glue 연결 유형은 여러 `format` 유형을 지원하므로 `GlueContext.write_dynamic_frame.from_options`와 같은 방법을 사용할 때 `format_options` 객체로 데이터 형식에 대한 정보를 지정해야 합니다.
+ `s3` - 자세한 내용은 AWS Glue: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 연결 유형 및 옵션을 참조하세요. 이 연결 유형(Python에서 [create\$1dynamic\$1frame\$1from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 및 [write\$1dynamic\$1frame\$1from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options), 그에 해당하는 스칼라 메서드 [def getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 및 [def getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat))을 지원하는 메서드에 대한 문서도 볼 수 있습니다.

  
+ `kinesis` - 자세한 내용은 AWS Glue: [Kinesis 연결 파라미터](aws-glue-programming-etl-connect-kinesis-home.md#aws-glue-programming-etl-connect-kinesis)의 ETL 연결 유형 및 옵션을 참조하세요. 이 연결 유형([create\$1data\$1frame\$1from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create-dataframe-from-options) 및 그에 해당하는 스칼라 메서드 [def createDataFrameFromOptions](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-createDataFrameFromOptions))을 지원하는 메서드에 대한 문서도 볼 수 있습니다.
+ `kafka` - 자세한 내용은 AWS Glue: [Kafka 연결 파라미터](aws-glue-programming-etl-connect-kafka-home.md#aws-glue-programming-etl-connect-kafka)의 ETL 연결 유형 및 옵션을 참조하세요. 이 연결 유형([create\$1data\$1frame\$1from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create-dataframe-from-options) 및 그에 해당하는 스칼라 메서드 [def createDataFrameFromOptions](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-createDataFrameFromOptions))을 지원하는 메서드에 대한 문서도 볼 수 있습니다.

일부 연결 유형은 `format_options`가 필요하지 않습니다. 예를 들어 일반적인 사용 과정에서 관계형 데이터베이스에 대한 JDBC 연결은 일관된 테이블형 데이터 형식으로 데이터를 검색하므로 JDBC 연결에서 읽을 때 `format_options`가 필요하지 않습니다.

Glue에서 데이터를 읽고 쓰는 일부 방법은 `format_options`가 필요하지 않습니다. 예를 들어, Glue 크롤러에서 `GlueContext.create_dynamic_frame.from_catalog` 및 AWS를 사용하는 경우. 크롤러는 데이터의 형태를 결정합니다. 크롤러를 사용할 때 AWS Glue 분류기는 데이터를 검사하여 데이터 형식을 표현하는 방법에 대한 현명한 결정을 내립니다. 그런 다음 AWS Glue ETL 스크립트 내에서 `GlueContext.create_dynamic_frame.from_catalog` 메서드로 데이터를 검색하는 데 사용할 수 있는 AWS Glue 데이터 카탈로그에 데이터 표현을 저장합니다. 크롤러를 사용하면 데이터 형식에 대한 정보를 수동으로 지정할 필요가 없습니다.

AWS Lake Formation 관리형 테이블에 액세스하는 작업의 경우 AWS Glue는 Lake Formation 관리형 테이블에서 지원되는 모든 포맷을 읽고 쓸 수 있도록 지원합니다. AWS Lake Formation 관리형 테이블에서 현재 지원되는 포맷 목록은 [AWS Lake Formation 개발자 가이드](https://docs.aws.amazon.com/lake-formation/latest/dg/governed-table-restrictions.html)의 *관리형 테이블에 대한 참고 사항 및 제한 사항*을 참조하세요.

**참고**  
Apache Parquet 쓰기의 경우 AWS Glue ETL은 Dynamic Frames에 최적화된 사용자 지정 Parquet 라이터 유형에 대한 옵션을 지정하여 관리형 테이블에 쓰는 기능만을 지원합니다. `parquet` 포맷을 사용하는 관리형 테이블에 쓰는 경우 테이블 파라미터의 `true` 값과 함께 `useGlueParquetWriter` 키를 추가해야 합니다.

**Topics**
+ [AWS Glue의 데이터 형식 전반에 걸친 기능 지원](#aws-glue-programming-etl-format-features)
+ [AWS Glue의 데이터 형식과 상호 작용하는 데 사용되는 파라미터](#aws-glue-programming-etl-format-parameters)
+ [AWS Glue에서 CSV 형식 사용](aws-glue-programming-etl-format-csv-home.md)
+ [AWS Glue에서 Parquet 형식 사용](aws-glue-programming-etl-format-parquet-home.md)
+ [AWS Glue에서 XML 형식 사용](aws-glue-programming-etl-format-xml-home.md)
+ [AWS Glue에서 Avro 형식 사용](aws-glue-programming-etl-format-avro-home.md)
+ [AWS Glue에서 grokLog 형식 사용](aws-glue-programming-etl-format-grokLog-home.md)
+ [AWS Glue에서 Ion 형식 사용](aws-glue-programming-etl-format-ion-home.md)
+ [AWS Glue에서 JSON 형식 사용](aws-glue-programming-etl-format-json-home.md)
+ [AWS Glue에서 ORC 형식 사용](aws-glue-programming-etl-format-orc-home.md)
+ [AWS Glue ETL 작업에서 데이터 레이크 프레임워크 사용](aws-glue-programming-etl-datalake-native-frameworks.md)
+ [공유 구성 참조](#aws-glue-programming-etl-format-shared-reference)

# AWS Glue에서 CSV 형식 사용
<a name="aws-glue-programming-etl-format-csv-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 CSV 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

 AWS Glue는 CSV(쉼표로 분리된 값) 형식 사용만 지원합니다. 이 형식은 최소 행 기반 데이터 형식입니다. CSV는 표준을 엄격하게 준수하지 않는 경우가 많지만 [RFC 4180](https://tools.ietf.org/html/rfc4180)과 [RFC 7111](https://tools.ietf.org/html/rfc7111)에서 자세한 정보를 참조할 수 있습니다.

AWS Glue를 사용하여 Amazon S3와 스트리밍 소스에서 CSV를 읽을 수 있을 뿐만 아니라 Amazon S3에 CSV를 쓸 수 있습니다. S3에서 CSV 파일이 포함된 `bzip` 및 `gzip` 아카이브를 읽고 쓸 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 CSV 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원됨 | 지원됨 | 지원됨 | 지원됨 | 지원됨 | 

## 예: S3에서 CSV 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-csv-read"></a>

 **사전 조건:** 읽고자 하는 CSV 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

 **구성:** 함수 옵션에서 `format="csv"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 리더와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 리더에서 `format_options`의 CSV 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [CSV 구성 참조](#aws-glue-programming-etl-format-csv-reference)를 참조하십시오.

다음 AWS Glue ETL 스크립트는 S3에서 CSV 파일 또는 폴더를 읽는 프로세스를 보여줍니다.

 `optimizePerformance` 구성 키를 통해 사용자 지정 CSV 리더에 일반적인 워크플로우에 대한 성능 최적화가 제공됩니다. 이 리더가 워크로드에 적합한지 확인하려면 [벡터화된 SIMD CSV 리더로 읽기 성능 최적화](#aws-glue-programming-etl-format-simd-csv-reader) 단원을 참조하십시오.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read CSV from S3
# For show, we handle a CSV with a header row.  Set the withHeader option.
# Consider whether optimizePerformance is right for your workflow.

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="csv",
    format_options={
        "withHeader": True,
        # "optimizePerformance": True,
    },
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read\
    .format("csv")\
    .option("header", "true")\
    .load("s3://s3path")
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
// Example: Read CSV from S3
// For show, we handle a CSV with a header row.  Set the withHeader option.
// Consider whether optimizePerformance is right for your workflow.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    
    val dynamicFrame = glueContext.getSourceWithFormat(
      formatOptions=JsonOptions("""{"withHeader": true}"""),
      connectionType="s3",
      format="csv",
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
  }
}
```

또한 스크립트(`org.apache.spark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
val dataFrame = spark.read
  .option("header","true")
  .format("csv")
  .load("s3://s3path“)
```

------

## 예: S3에 CSV 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-csv-write"></a>

 **사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

 **구성:** 함수 옵션에서 `format="csv"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 라이터와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 작업에서 `format_options`에 있는 파일의 내용을 쓰는 방법을 구성할 수 있습니다. 자세한 내용은 [CSV 구성 참조](#aws-glue-programming-etl-format-csv-reference)를 참조하십시오. 다음 AWS Glue ETL 스크립트는 S3로 CSV 파일 및 폴더를 쓰는 프로세스를 보여줍니다.

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

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Write CSV to S3
# For show, customize how we write string type values.  Set quoteChar to -1 so our values are not quoted.

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    connection_options={"path": "s3://s3path"},
    format="csv",
    format_options={
        "quoteChar": -1,
    },
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame.write\
    .format("csv")\
    .option("quote", None)\
    .mode("append")\
    .save("s3://s3path")
```

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

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
// Example: Write CSV to S3
// For show, customize how we write string type values. Set quoteChar to -1 so our values are not quoted.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    
    glueContext.getSinkWithFormat(
        connectionType="s3",
        options=JsonOptions("""{"path": "s3://s3path"}"""),
        format="csv"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

또한 스크립트(`org.apache.spark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame.write
    .format("csv")
    .option("quote", null)
    .mode("Append")
    .save("s3://s3path")
```

------

## CSV 구성 참조
<a name="aws-glue-programming-etl-format-csv-reference"></a>

AWS Glue 라이브러리가 `format="csv"`를 지정한 곳이라면 어디에서든 다음 `format_options`을 사용할 수 있습니다.
+ `separator` - 구분 기호 문자열을 지정합니다. 기본값은 쉼표(,)이지만, 다른 문자도 지정할 수 있습니다.
  + **유형:** 텍스트, **기본값:** `","`
+ `escaper` - 이스케이프 처리에 사용할 문자를 지정합니다. 이 옵션은 CSV 파일을 읽을 때만 사용되며 쓸 때는 사용되지 않습니다. 활성화된 경우 바로 다음에 나오는 문자가 잘 알려진 이스케이프 세트(`\n`, `\r`, `\t` 및 `\0`)를 제외하고는 있는 그대로 사용됩니다.
  + **유형:** 텍스트, **기본값:** 없음
+ `quoteChar` - 인용에 사용할 문자를 지정합니다. 기본값은 큰 따옴표(")입니다. 전체 인용을 해제하려면 이 값을 `-1`로 설정합니다.
  + **유형:** 텍스트, **기본값:** `'"'`
+ `multiLine` - 단일 기록이 다양한 라인을 포괄할 수 있는지 여부를 지정합니다. 필드가 인용된 새로운 라인 문자를 포함할 때 발생합니다. 이 옵션을 `True`로 설정해야 기록이 여러 라인을 포괄할 수 있습니다. `multiLine`을 활성화하면 구문 분석하는 동안 더 신중한 파일 분할이 필요하므로 성능이 저하될 수 있습니다.
  + **유형:** 부울, **기본값:** `false`
+ `withHeader` - 첫 번째 라인을 헤더로 취급할지 여부를 지정합니다. 이 옵션은 `DynamicFrameReader` 클래스에서 사용할 수 있습니다.
  + **유형:** 부울, **기본값:** `false`
+ `writeHeader` - 헤더를 작성하여 출력할지 여부를 지정합니다. 이 옵션은 `DynamicFrameWriter` 클래스에서 사용할 수 있습니다.
  + **유형:** 부울, **기본값:** `true`
+ `skipFirst`- 첫 번째 데이터 라인을 건너뛸지 여부를 지정합니다.
  + **유형:** 부울, **기본값:** `false`
+ `optimizePerformance` - Apache Arrow 기반 열 포맷 메모리 포맷과 함께 고급 SIMD CSV 리더를 사용할지 여부를 지정합니다. AWS Glue 3.0 이상에서만 사용 가능합니다.
  + **유형:** 부울, **기본값:** `false`
+ `strictCheckForQuoting` - CSV를 쓸 때 Glue는 문자열로 해석되는 값에 따옴표를 추가할 수 있습니다. 이는 기록된 내용이 모호하지 않도록 하기 위해서입니다. 기록할 내용을 결정할 때 시간을 절약하기 위해 Glue는 따옴표가 필요하지 않은 특정 상황에서 인용할 수 있습니다. 엄격한 검사를 활성화하면 보다 컴퓨팅 집약적인 작업을 수행하고 필요한 경우에만 인용합니다. AWS Glue 3.0 이상에서만 사용 가능합니다.
  + **유형:** 부울, **기본값:** `false`

## 벡터화된 SIMD CSV 리더로 읽기 성능 최적화
<a name="aws-glue-programming-etl-format-simd-csv-reader"></a>

AWS Glue 버전 3.0에는 행 기반 CSV 리더에 비해 전반적인 작업 속도를 크게 높일 수 있는 최적화된 CSV 리더가 추가되었습니다.

 최적화된 리더:
+ CPU SIMD 명령을 사용하여 디스크에서 읽기
+ 레코드를 열 기반 형식으로 메모리에 즉시 쓰기(Apache Arrow) 
+ 레코드를 배치로 분할

이렇게 하면 나중에 레코드가 일괄 처리되거나 열 기반 형식으로 변환될 때 처리 시간이 절약됩니다. 스키마를 변경하거나 열별로 데이터를 검색하는 경우를 예로 들 수 있습니다.

최적화된 리더를 사용하려면 `format_options` 또는 테이블 속성에서 `"optimizePerformance"`를 `true`로 설정합니다.

```
glueContext.create_dynamic_frame.from_options(
    frame = datasource1,
    connection_type = "s3", 
    connection_options = {"paths": ["s3://s3path"]}, 
    format = "csv", 
    format_options={
        "optimizePerformance": True, 
        "separator": ","
        }, 
    transformation_ctx = "datasink2")
```

**벡터화된 CSV 리더에 대한 제한 사항**  
벡터화된 CSV 리더의 제한 사항:
+ `multiLine` 및 `escaper` 포맷 옵션은 지원되지 않습니다. 큰따옴표 문자(`'"'`)의 기본값 `escaper`가 사용됩니다. 이러한 옵션을 설정하면 AWS Glue는 행 기반 CSV 리더를 사용하는 상태로 자동으로 돌아갑니다.
+ [ChoiceType](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-crawler-pyspark-extensions-types.html#aws-glue-api-crawler-pyspark-extensions-types-awsglue-choicetype)으로 DynamicFrame 생성이 지원되지 않습니다.
+ [오류 레코드](https://docs.aws.amazon.com/glue/latest/dg/glue-etl-scala-apis-glue-dynamicframe-class.html#glue-etl-scala-apis-glue-dynamicframe-class-defs-errorsAsDynamicFrame)로 DynamicFrame 생성이 지원되지 않습니다.
+ 일본어 또는 중국어와 같은 멀티바이트 문자가 포함된 CSV 파일 읽기가 지원되지 않습니다.

# AWS Glue에서 Parquet 형식 사용
<a name="aws-glue-programming-etl-format-parquet-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 Parquet 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 Parquet 형식 사용을 지원합니다. 이 형식은 성능 중심의 열 기반 데이터 형식입니다. 표준 기관의 형식에 대한 소개는 [Apache Parquet 설명서 개요](https://parquet.apache.org/docs/overview/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3와 스트리밍 소스에서 Parquet 파일을 읽을 수 있을 뿐만 아니라 Amazon S3에 Parquet 파일을 쓸 수 있습니다. S3에서 Parquet 파일이 포함된 `bzip` 및 `gzip` 아카이브를 읽고 쓸 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 Parquet 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원됨 | 지원됨 | 지원됨 | 지원되지 않음 | 지원\$1 | 

\$1 AWS Glue 버전 1.0 이상에서 지원

## 예: S3에서 Parquet 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-parquet-read"></a>

**사전 조건:** 읽고자 하는 Parquet 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

 **구성:** 함수 옵션에서 `format="parquet"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다.

`connection_options`에서 리더와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)

 리더에서 `format_options`의 Parquet 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [Parquet 구성 참조](#aws-glue-programming-etl-format-parquet-reference)를 참조하십시오.

다음 AWS Glue ETL 스크립트는 S3에서 Parquet 파일 또는 폴더를 읽는 프로세스를 보여줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read Parquet from S3

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type = "s3", 
    connection_options = {"paths": ["s3://s3path/"]}, 
    format = "parquet"
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read.parquet("s3://s3path/")
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 메서드를 사용합니다.

```
// Example: Read Parquet from S3

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    
    val dynamicFrame = glueContext.getSourceWithFormat(
      connectionType="s3",
      format="parquet",
      options=JsonOptions("""{"paths": ["s3://s3path"]}""")
    ).getDynamicFrame()
  }
}
```

또한 스크립트(`org.apache.spark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
spark.read.parquet("s3://s3path/")
```

------

## 예: S3에 Parquet 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-parquet-write"></a>

**사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

 **구성:** 함수 옵션에서 `format="parquet"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다.

`connection_options`에서 라이터가 S3와 상호 작용하는 방식을 추가로 변경할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 작업에서 `format_options`에 있는 파일의 내용을 쓰는 방법을 구성할 수 있습니다. 자세한 내용은 [Parquet 구성 참조](#aws-glue-programming-etl-format-parquet-reference)를 참조하십시오.

다음 AWS Glue ETL 스크립트는 S3로 Parquet 파일 및 폴더를 쓰는 프로세스를 보여줍니다.

`useGlueParquetWriter` 구성 키를 통해 사용자 지정 Parquet 라이터에 DynamicFrame에 대한 성능 최적화가 제공됩니다. 이 라이터가 워크로드에 적합한지 확인하려면 [Glue Parquet 라이터](#aws-glue-programming-etl-format-glue-parquet-writer)를 참조하세요.

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

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Write Parquet to S3
# Consider whether useGlueParquetWriter is right for your workflow.

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    format="parquet",
    connection_options={
        "path": "s3://s3path",
    },
    format_options={
        # "useGlueParquetWriter": True,
    },
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.parquet("s3://s3path/")
```

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

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
// Example: Write Parquet to S3
// Consider whether useGlueParquetWriter is right for your workflow.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    
    glueContext.getSinkWithFormat(
        connectionType="s3",
        options=JsonOptions("""{"path": "s3://s3path"}"""),
        format="parquet"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

또한 스크립트(`org.apache.spark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.parquet("s3://s3path/")
```

------

## Parquet 구성 참조
<a name="aws-glue-programming-etl-format-parquet-reference"></a>

AWS Glue 라이브러리가 `format="parquet"`을 지정한 어디에서나 다음 `format_options`를 사용할 수 있습니다.
+ `useGlueParquetWriter` - DynamicFrame 워크플로에 대한 성능 최적화가 포함된 사용자 지정 Parquet 라이터의 사용을 지정합니다. 자세한 내용은 [Glue Parquet 라이터](#aws-glue-programming-etl-format-glue-parquet-writer)를 참조하세요.
  + **유형:** 부울, **기본값:**`false`
+ `compression` - 사용되는 압축 코덱을 지정합니다. 값은 `org.apache.parquet.hadoop.metadata.CompressionCodecName`과 완벽하게 호환됩니다.
  + **유형:** 열거 텍스트, **기본값:** `"snappy"`
  + 값: `"uncompressed"`, `"snappy"`, `"gzip"` 및 `"lzo"`
+ `blockSize` - 메모리에 버퍼링되는 행 그룹의 크기(바이트 단위)를 지정합니다. 성능 튜닝에 사용합니다. 크기는 정확히 메가바이트 수로 나눠야 합니다.
  + **유형:** 숫자, **기본값:**`134217728`
  + 기본값은 128MB입니다.
+ `pageSize` - 페이지의 크기를 바이트 단위로 지정합니다. 성능 튜닝에 사용합니다. 페이지는 단일 레코드에 액세스하기 위해 완전하게 읽어야 하는 가장 작은 단위입니다.
  + **유형:** 숫자, **기본값:**`1048576`
  + 기본값은 1MB입니다.

**참고**  
또한 SparkSQL 기초 코드에 의해 수락된 옵션은 `connection_options` 맵 파라미터를 거쳐 SparkSQL 기초 코드로 넘겨질 수 있습니다. 예를 들어 AWS Glue Spark 리더에 대해 [mergeSchema](https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#schema-merging)와 같은 Spark 구성을 설정하여 모든 파일의 스키마를 병합할 수 있습니다.

## AWS Glue Parquet 라이터를 사용한 쓰기 성능 최적화
<a name="aws-glue-programming-etl-format-glue-parquet-writer"></a>

**참고**  
 AWS Glue Parquet 라이터는 예전에 `glueparquet` 형식 유형을 통해 액세스되었습니다. 이 액세스 패턴은 더 이상 지원되지 않습니다. 대신 `useGlueParquetWriter`이 활성화된 `parquet` 유형을 사용합니다.

AWS Glue Parquet 라이터는 더 빠른 Parquet 파일 쓰기가 가능하도록 성능이 향상되었습니다. 기존 라이터는 쓰기 전에 스키마를 컴퓨팅합니다. Parquet 형식은 빠르게 검색할 수 있는 방식으로 스키마를 저장하지 않으므로 시간이 걸릴 수 있습니다. AWS Glue Parquet 라이터를 사용하는 경우 사전 컴퓨팅된 스키마가 필요하지 않습니다. 데이터가 들어오면 라이터는 스키마를 동적으로 컴퓨팅 및 수정합니다.

`useGlueParquetWriter`를 지정하는 경우 다음 제한에 유의하세요.
+ 라이터는 열 추가 또는 제거와 같은 스키마 개선만 지원하고 `ResolveChoice`와 같은 열 유형 변경은 지원하지 않습니다.
+ 작성기는 빈 DataFrames 작성(예: 스키마 전용 파일 작성)을 지원하지 않습니다. `enableUpdateCatalog=True`를 설정하여 AWS Glue 데이터 카탈로그와 통합할 때 빈 DataFrame을 작성하려고 해도 데이터 카탈로그가 업데이트되지 않습니다. 그러면 스키마 없이 데이터 카탈로그에 테이블이 생성됩니다.

변형에 이러한 제한이 필요하지 않은 경우 AWS Glue Parquet 라이터를 켜면 성능이 향상됩니다.

# AWS Glue에서 XML 형식 사용
<a name="aws-glue-programming-etl-format-xml-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 XML 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 XML 형식 사용을 지원합니다. 이 형식은 행이나 열을 기반으로 하지 않는 고도로 구성 가능하고 엄격하게 정의된 데이터 구조를 나타냅니다. XML은 고도로 표준화되어 있습니다. 표준 기관의 형식에 대한 소개는 [XML 필수 사항](https://www.w3.org/standards/xml/core)을 참조하십시오.

AWS Glue를 사용하여 Amazon S3는 물론 XML 파일이 포함된 `bzip` 및 `gzip` 아카이브에서 XML 파일을 읽을 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 XML 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원되지 않음 | 지원되지 않음 | 지원 | 지원 | 

## 예: S3에서 XML 읽기
<a name="aws-glue-programming-etl-format-xml-read"></a>

 XML 리더는 XML 태그 이름을 사용합니다. 입력 내에 해당 태그가 있는 요소를 검사하여 스키마를 추론하고 DynamicFrame을 해당 값으로 채웁니다. AWS Glue XML 기능은 [Apache Spark용 XML 데이터 소스](https://github.com/databricks/spark-xml)와 비슷하게 작동합니다. 이 리더를 해당 프로젝트의 문서와 비교하면 기본 동작에 대한 통찰력을 얻을 수 있습니다.

**사전 조건:** 읽고자 하는 CSV 파일 또는 폴더에 대한 S3 경로(`s3path`), 그리고 XML 파일에 관한 약간의 정보가 필요합니다. 읽으려는 XML 요소에 대한 태그(`xmlTag`)도 필요합니다.

 **구성:** 함수 옵션에서 `format="xml"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 리더와 S3가 상호 작용하는 방식을 추가로 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) `format_options`에서 `rowTag` 키를 사용하여 `xmlTag`를 지정합니다. 리더에서 `format_options`의 XML 파일을 해석하는 방법을 추가로 구성할 수 있습니다. 자세한 내용은 [XML 구성 참조](#aws-glue-programming-etl-format-xml-reference)를 참조하십시오.

다음 AWS Glue ETL 스크립트는 S3에서 XML 파일 또는 폴더를 읽는 프로세스를 보여줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read XML from S3
# Set the rowTag option to configure the reader.

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="xml",
    format_options={"rowTag": "xmlTag"},
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read\
    .format("xml")\
    .option("rowTag", "xmlTag")\
    .load("s3://s3path")
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
// Example: Read XML from S3
// Set the rowTag option to configure the reader.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.sql.SparkSession

val glueContext = new GlueContext(SparkContext.getOrCreate())
val sparkSession: SparkSession = glueContext.getSparkSession

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val dynamicFrame = glueContext.getSourceWithFormat(
      formatOptions=JsonOptions("""{"rowTag": "xmlTag"}"""), 
      connectionType="s3", 
      format="xml", 
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
}
```

또한 스크립트(`org.apache.spark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
val dataFrame = spark.read
  .option("rowTag", "xmlTag")
  .format("xml")
  .load("s3://s3path“)
```

------

## XML 구성 참조
<a name="aws-glue-programming-etl-format-xml-reference"></a>

AWS Glue 라이브러리가 `format="xml"`를 지정한 곳이라면 어디에서든 다음 `format_options`을 사용할 수 있습니다.
+ `rowTag` - 파일의 XML 태그를 지정하여 태그를 열로 취급합니다. 열 태그는 자기 복제를 할 수 없습니다.
  + **유형:** 텍스트, **필수**
+ `encoding` - 문자 인코딩을 지정합니다. 런타임 환경에서 지원하는 [Charset](https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html)의 이름 또는 별칭이 될 수 있습니다. 인코딩 지원에 대해 구체적으로 보장하지는 않지만 주요 인코딩은 작동할 것입니다.
  + **유형:** 텍스트, **기본값:** `"UTF-8"`
+ `excludeAttribute` - 요소에서 속성을 제외할지 여부를 지정합니다.
  + **유형:** 부울, **기본값:** `false`
+ `treatEmptyValuesAsNulls` - 공백을 null 값으로 취급할지 여부를 지정합니다.
  + **유형:** 부울, **기본값:** `false`
+ `attributePrefix` - 하위 요소 텍스트와 구별하기 위한 속성용 접두사. 이 접두사는 필드 이름으로 사용됩니다.
  + **유형:** 텍스트, **기본값:** `"_"`
+ `valueTag` - 하위 요소가 없는 요소에 속성이 있는 값에 사용되는 태그.
  + **유형:** 텍스트, **기본값:** `"_VALUE"`
+ `ignoreSurroundingSpaces` - 값을 둘러싸는 공백을 무시할지 여부를 지정합니다.
  + **유형:** 부울, **기본값:** `false`
+ `withSchema` - 추론된 스키마를 재정의하려는 상황에서 예상되는 스키마를 포함합니다. 이 옵션을 사용하지 않으면 AWS Glue는 XML 데이터에서 스키마를 유추합니다.
  + **유형:** 텍스트, **기본값:** 해당 사항 없음
  + 값은 `StructType`을 나타내는 JSON 객체여야 합니다.

## XML 스키마를 수동으로 지정
<a name="aws-glue-programming-etl-format-xml-withschema"></a>

**수동 XML 스키마 예**

`withSchema` 포맷 옵션을 사용하여 XML 데이터에 대한 스키마를 지정하는 예입니다.

```
from awsglue.gluetypes import *

schema = StructType([ 
  Field("id", IntegerType()),
  Field("name", StringType()),
  Field("nested", StructType([
    Field("x", IntegerType()),
    Field("y", StringType()),
    Field("z", ChoiceType([IntegerType(), StringType()]))
  ]))
])

datasource0 = create_dynamic_frame_from_options(
    connection_type, 
    connection_options={"paths": ["s3://xml_bucket/someprefix"]},
    format="xml", 
    format_options={"withSchema": json.dumps(schema.jsonValue())},
    transformation_ctx = ""
)
```

# AWS Glue에서 Avro 형식 사용
<a name="aws-glue-programming-etl-format-avro-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 Avro 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 Avro 형식 사용을 지원합니다. 이 형식은 성능 중심의 행 기반 데이터 형식입니다. 표준 기관의 형식에 대한 소개는 [Apache Avro 1.8.2 설명서 개요](https://avro.apache.org/docs/1.8.2/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3와 스트리밍 소스에서 Avro 파일을 읽을 수 있을 뿐만 아니라 Amazon S3에 Avro 파일을 쓸 수 있습니다. S3에서 Avro 파일이 포함된 `bzip2` 및 `gzip` 아카이브를 읽고 쓸 수 있습니다. 또한 Avro 파일이 포함된 `deflate`, `snappy`, `xz` 아카이브를 쓸 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 Avro 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여 줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원 | 지원\$1 | 지원되지 않음 | 지원 | 

\$1제한적으로 지원됩니다. 자세한 내용은 [Avro 스트리밍 소스에 대한 참고 사항 및 제한 사항](add-job-streaming.md#streaming-avro-notes) 섹션을 참조하세요.

## 예: S3에서 Avro 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-avro-read"></a>

** 사전 조건:** 읽으려는 Avro 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

**구성:** 함수 옵션에서 `format="avro"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 리더와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 입력 및 출력에 대한 데이터 형식 옵션을 참조하세요. 리더에서 `format_options`의 Avro 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [Avro 구성 참조](#aws-glue-programming-etl-format-avro-reference)를 참조하세요.

다음 AWS Glue ETL 스크립트는 S3에서 Avro 파일 또는 폴더를 읽는 프로세스를 보여 줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="avro"
)
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.sql.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      connectionType="s3",
      format="avro",
      options=JsonOptions("""{"paths": ["s3://s3path"]}""")
    ).getDynamicFrame()
  }
```

------

## 예: S3에 Avro 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-avro-write"></a>

**사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

**구성:** 함수 옵션에서 `format="avro"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 라이터가 S3와 상호 작용하는 방식을 추가로 변경할 수 있습니다. 자세한 내용은 AWS Glue: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 입력 및 출력에 대한 데이터 형식 옵션을 참조하세요. 작가가 `format_options`에서 Avro 파일을 해석하는 방식을 변경할 수 있습니다. 자세한 내용은 [Avro 구성 참조](#aws-glue-programming-etl-format-avro-reference)를 참조하세요.

다음 AWS Glue ETL 스크립트는 S3로 Avro 파일 및 폴더를 쓰는 프로세스를 보여줍니다.

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

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    format="avro",
    connection_options={
        "path": "s3://s3path"
    }
)
```

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

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    glueContext.getSinkWithFormat(
      connectionType="s3",
      options=JsonOptions("""{"path": "s3://s3path"}"""),
      format="avro"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

------

## Avro 구성 참조
<a name="aws-glue-programming-etl-format-avro-reference"></a>

AWS Glue 라이브러리가 `format="avro"`를 지정한 곳이라면 어디에서든 다음 `format_options` 값을 사용할 수 있습니다.
+ `version` - 지원하는 Apache Avro 리더/라이터 포맷의 버전을 지정합니다. 기본값은 "1.7"입니다. `format_options={"version": “1.8”}`를 지정해 Avro 논리적 유형 읽기 및 쓰기를 활성화할 수 있습니다. 자세한 내용은 [Apache Avro 1.7.7 사양](https://avro.apache.org/docs/1.7.7/spec.html) 및 [Apache Avro 1.8.2 사양](https://avro.apache.org/docs/1.8.2/spec.html)을 참조하십시오.

  Apache Avro 1.8 커넥터는 다음과 같은 논리적 유형 변환을 지원합니다.

리더의 경우: 다음 테이블은 Avro 리더 1.7 및 1.8을 위한 Avro 데이터 유형(논리적 유형, Avro 기본 유형)과 AWS Glue `DynamicFrame` 데이터 유형 간 변환을 보여줍니다.


| Avro 데이터 형식: 논리적 유형 | Avro 데이터 형식: Avro 기본 유형 | GlueDynamicFrame 데이터 유형:Avro 리더 1.7 | GlueDynamicFrame 데이터 유형: Avro 리더 1.8 | 
| --- | --- | --- | --- | 
| 10진수 | bytes | BINARY | 10진수 | 
| 10진수 | 고정 | BINARY | 10진수 | 
| 날짜 | int | INT | 날짜 | 
| 시간(밀리초) | int | INT | INT | 
| 시간(마이크로초) | long | LONG | LONG | 
| 타임스탬프(밀리초) | long | LONG | Timestamp | 
| 타임스탬프(마이크로초) | long | LONG | LONG | 
| 기간(논리적 유형 아님) | 고정(12) | BINARY | BINARY | 

라이터의 경우: 다음 테이블은 Avro 라이터 1.7 및 1.8을 위한 AWS Glue `DynamicFrame` 데이터 유형과 Avro 데이터 유형 간 변환을 보여줍니다.


| AWS Glue `DynamicFrame` 데이터 유형 | Avro 데이터 형식:Avro 라이터 1.7 | Avro 데이터 형식:Avro 라이터 1.8 | 
| --- | --- | --- | 
| 10진수 | String | decimal | 
| 날짜 | String | date | 
| Timestamp | String | timestamp-micros | 

## Avro Spark DataFrame 지원
<a name="aws-glueprogramming-etl-format-avro-dataframe-support"></a>

Spark DataFrame API에서 Avro를 사용하려면 해당 Spark 버전에 대한 Spark Avro 플러그인을 설치해야 합니다. 작업에서 사용할 수 있는 Spark 버전은 AWS Glue 버전에 따라 결정됩니다. Spark 버전에 대한 자세한 내용은 [AWS Glue 버전](release-notes.md) 섹션을 참조하세요. 이 플러그인은 Apache에서 유지 관리하며 구체적인 지원을 보장하지는 않습니다.

AWS Glue 2.0에서 - Spark Avro 플러그인의 버전 2.4.3을 사용하세요. 이 JAR는 Maven Central에서 찾을 수 있습니다. [org.apache.spark:spark-avro\$12.12:2.4.3](https://search.maven.org/artifact/org.apache.spark/spark-avro_2.12/3.1.1/jar)을 참조하세요.

AWS Glue 3.0에서 - Spark Avro 플러그인의 버전 3.1.1을 사용하세요. 이 JAR는 Maven Central에서 찾을 수 있습니다. [org.apache.spark:spark-avro\$12.12:3.1.1](https://search.maven.org/artifact/org.apache.spark/spark-avro_2.12/3.1.1/jar)을 참조하세요.

추가 JAR을 AWS Glue ETL 작업에 포함하려면 `--extra-jars` 작업 파라미터를 사용하세요. 작업 파라미터에 대한 자세한 내용을 알아보려면 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md) 섹션을 참조하세요. AWS Management Console에서 이 매개 변수를 구성할 수도 있습니다.

# AWS Glue에서 grokLog 형식 사용
<a name="aws-glue-programming-etl-format-grokLog-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 느슨하게 구조화된 일반 텍스트 형식으로 저장되거나 전송되는 경우 이 문서에서는 Grok 패턴을 통해 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 Grok 패턴 사용을 지원합니다. Grok 패턴은 정규 표현식 캡처 그룹과 유사합니다. 이들은 일반 텍스트 파일에서 문자 시퀀스의 패턴을 인식하여 유형과 목적을 부여합니다. AWS Glue에서 주요 목적은 로그를 읽는 것입니다. 저자의 Grok에 대한 소개는 [Logstash 참조: Grok 필터 플러그인](https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html)을 참조하세요.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 해당 사항 없음 | 지원 | 지원 | 지원되지 않음 | 

## grokLog 구성 참조
<a name="aws-glue-programming-etl-format-groklog-reference"></a>

`format="grokLog"`으로 다음 `format_options` 값을 사용할 수 있습니다.
+ `logFormat` - 로그 포맷과 일치하는 Grok 패턴을 지정합니다.
+ `customPatterns` - 여기서 사용된 Grok 패턴을 지정합니다.
+ `MISSING` - 누락된 값을 식별하는 데 사용된 신호를 지정합니다. 기본값은 `'-'`입니다.
+ `LineCount` - 각 로그 기록의 라인 수를 지정합니다. 기본값은 `'1'`이며 현재 단일 라인 기록만 지원합니다.
+ `StrictMode` - 제한 모드를 설정할지 여부를 지정하는 부울 값. 제한 모드에서 리더는 자동적으로 유형을 전환하거나 복구하지 않습니다. 기본값은 `"false"`입니다.

# AWS Glue에서 Ion 형식 사용
<a name="aws-glue-programming-etl-format-ion-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 Ion 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 Ion 형식 사용을 지원합니다. 이 형식은 교환 가능한 이진 및 일반 텍스트 표현으로 데이터 구조(행 또는 열 기반이 아님)를 나타냅니다. 저자의 형식에 대한 소개는 [Amazon Ion](https://amzn.github.io/ion-docs/)을 참조하세요. (자세한 내용은 [Amazon Ion 상세 정보](https://amzn.github.io/ion-docs/spec.html)를 참조하십시오.)

AWS Glue를 사용하여 Amazon S3에서 Ion 파일을 읽을 수 있습니다. S3에서 Ion 파일이 포함된 `bzip` 및 `gzip` 아카이브를 읽을 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 Ion 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여 줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원되지 않음 | 지원되지 않음 | 지원 | 지원되지 않음 | 

## 예: S3에서 Ion 파일 및 폴더 읽기
<a name="aws-glue-programming-etl-format-ion-read"></a>

** 사전 조건:** 읽으려는 Ion 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

**구성:** 함수 옵션에서 `format="json"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 리더와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 

다음 AWS Glue ETL 스크립트는 S3에서 Ion 파일 또는 폴더를 읽는 프로세스를 보여 줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read ION from S3

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="ion"
)
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
// Example: Read ION from S3

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      connectionType="s3",
      format="ion",
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
  }
}
```

------

## Ion 구성 참조
<a name="aws-glue-programming-etl-format-ion-reference"></a>

`format="ion"`을 위한 `format_options` 값은 없습니다.

# AWS Glue에서 JSON 형식 사용
<a name="aws-glue-programming-etl-format-json-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 JSON 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 JSON 형식 사용을 지원합니다. 이 형식은 행이나 열을 기반으로 하지 않는 일관된 모양이지만 유연한 내용의 데이터 구조를 나타냅니다. JSON은 여러 기관에서 발행한 병렬 표준으로 정의되며 그 중 하나는 ECMA-404입니다. 일반적으로 참조되는 소스의 형식에 대한 소개는 [JSON 소개](https://www.json.org/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3에서 JSON 파일과 `bzip` 및 `gzip` 압축된 JSON 파일을 읽을 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원 | 지원 | 지원 | 지원 | 

## 예: S3에서 JSON 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-json-read"></a>

** 사전 조건:** 읽으려는 JSON 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

**구성:** 함수 옵션에서 `format="json"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. 연결 옵션에서 읽기 작업이 s3를 통과하는 방법을 추가로 변경할 수 있습니다. 자세한 내용은 [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)를 참조하세요. 리더에서 `format_options`의 JSON 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [JSON 구성 참조](#aws-glue-programming-etl-format-json-reference)를 참조하세요.

 다음 AWS Glue ETL 스크립트는 S3에서 JSON 파일 또는 폴더를 읽는 프로세스를 보여 줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read JSON from S3
# For show, we handle a nested JSON file that we can limit with the JsonPath parameter
# For show, we also handle a JSON where a single entry spans multiple lines
# Consider whether optimizePerformance is right for your workflow.

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="json",
    format_options={
        "jsonPath": "$.id",
        "multiline": True,
        # "optimizePerformance": True, -> not compatible with jsonPath, multiline
    }
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read\
    .option("multiline", "true")\
    .json("s3://s3path")
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
// Example: Read JSON from S3
// For show, we handle a nested JSON file that we can limit with the JsonPath parameter
// For show, we also handle a JSON where a single entry spans multiple lines
// Consider whether optimizePerformance is right for your workflow.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      formatOptions=JsonOptions("""{"jsonPath": "$.id", "multiline": true, "optimizePerformance":false}"""),
      connectionType="s3",
      format="json",
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
val dataFrame = spark.read
    .option("multiline", "true")
    .json("s3://s3path")
```

------

## 예: S3에 JSON 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-json-write"></a>

** 사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

**구성:** 함수 옵션에서 `format="json"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 라이터가 S3와 상호 작용하는 방식을 추가로 변경할 수 있습니다. 자세한 내용은 AWS Glue: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 입력 및 출력에 대한 데이터 형식 옵션을 참조하세요. 작성기에서 `format_options`의 JSON 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [JSON 구성 참조](#aws-glue-programming-etl-format-json-reference)를 참조하세요.

다음 AWS Glue ETL 스크립트는 S3에서 JSON 파일 또는 폴더를 쓰는 프로세스를 보여 줍니다.

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

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Write JSON to S3

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    connection_options={"path": "s3://s3path"},
    format="json"
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.json("s3://s3path/")
```

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

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
// Example: Write JSON to S3

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    glueContext.getSinkWithFormat(
        connectionType="s3",
        options=JsonOptions("""{"path": "s3://s3path"}"""),
        format="json"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.json("s3://s3path")
```

------

## JSON 구성 참조
<a name="aws-glue-programming-etl-format-json-reference"></a>

`format="json"`으로 다음 `format_options` 값을 사용할 수 있습니다.
+ `jsonPath` - 레코드로 읽을 객체를 식별하는 [JsonPath](https://github.com/json-path/JsonPath) 표현식. 이것은 외부 배열 안에 중첩된 레코드가 파일에 있을 때 특히 유용합니다. 예를 들어, 다음 JsonPath 표현식은 JSON 객체의 `id` 필드를 대상으로 합니다.

  ```
  format="json", format_options={"jsonPath": "$.id"}
  ```
+ `multiline` - 단일 기록이 다양한 라인을 포괄할 수 있는지 여부를 지정하는 부울 값. 필드가 인용된 새로운 라인 문자를 포함할 때 발생합니다. 이 옵션을 `"true"`로 설정해야 기록이 여러 라인을 포괄할 수 있습니다. 기본값은 `"false"`이라서 파싱 동안 더 많은 공격적 파일 쪼개기가 가능합니다.
+ `optimizePerformance` - Apache Arrow 기반 열 포맷 메모리 포맷과 함께 고급 SIMD JSON 리더를 사용할지 여부를 지정하는 부울 값입니다. AWS Glue 3.0에서만 사용 가능합니다. `multiline` 또는 `jsonPath`와 호환되지 않습니다. 이러한 옵션 중 하나를 제공하면 AWS Glue에서 표준 리더로 돌아갑니다.
+ `withSchema` - [XML 스키마를 수동으로 지정](aws-glue-programming-etl-format-xml-home.md#aws-glue-programming-etl-format-xml-withschema)에 설명된 형식으로 테이블 스키마를 지정하는 문자열 값입니다. 비카탈로그 연결에서 읽을 때 `optimizePerformance`에만 사용됩니다.

## Apache Arrow 열 포맷으로 벡터화된 SIMD JSON 리더 사용
<a name="aws-glue-programming-etl-format-simd-json-reader"></a>

AWS Glue 버전 3.0은 JSON 데이터에 대한 벡터화된 리더를 추가합니다. 이 리더는 특정 조건에서 표준 리더에 비해 2배 더 빠른 성능을 발휘합니다. 이 리더에는 사용하기 전에 사용자가 알아야 할 특정 제한 사항이 있습니다(이 섹션에 설명되어 있음).

최적화된 리더를 사용하려면 `format_options` 또는 테이블 속성에서 `"optimizePerformance"`를 True로 설정합니다. 또한 카탈로그에서 읽지 않는 한 `withSchema`를 제공해야 합니다. `withSchema`는 [XML 스키마를 수동으로 지정](aws-glue-programming-etl-format-xml-home.md#aws-glue-programming-etl-format-xml-withschema)에 설명된 대로 입력을 기대합니다.

```
// Read from S3 data source        
glueContext.create_dynamic_frame.from_options(
    connection_type = "s3", 
    connection_options = {"paths": ["s3://s3path"]}, 
    format = "json", 
    format_options={
        "optimizePerformance": True,
        "withSchema": SchemaString
        })    
 
// Read from catalog table
glueContext.create_dynamic_frame.from_catalog(
    database = database, 
    table_name = table, 
    additional_options = {
    // The vectorized reader for JSON can read your schema from a catalog table property.
        "optimizePerformance": True,
        })
```

AWS Glue 라이브러리에서 *SchemaString* 구축에 대한 자세한 내용은 [PySpark 확장 유형](aws-glue-api-crawler-pyspark-extensions-types.md) 섹션을 참조하세요.

**벡터화된 CSV 리더에 대한 제한 사항**  
다음과 같은 제한 사항이 있습니다.
+ 중첩된 객체 또는 배열 값이 있는 JSON 요소는 지원되지 않습니다. 제공 시 AWS Glue는 표준 리더로 돌아갑니다.
+ 카탈로그에서 또는 `withSchema`를 사용하여 스키마를 제공해야 합니다.
+ `multiline` 또는 `jsonPath`와 호환되지 않습니다. 이러한 옵션 중 하나를 제공하면 AWS Glue에서 표준 리더로 돌아갑니다.
+ 입력 스키마와 일치하지 않는 입력 레코드를 제공하면 리더가 실패할 수 있습니다.
+ [오류 레코드](https://docs.aws.amazon.com/glue/latest/dg/glue-etl-scala-apis-glue-dynamicframe-class.html#glue-etl-scala-apis-glue-dynamicframe-class-defs-errorsAsDynamicFrame)는 생성되지 않습니다.
+ 일본어 또는 중국어와 같은 멀티바이트 문자가 포함된 JSON 파일은 지원되지 않습니다.

# AWS Glue에서 ORC 형식 사용
<a name="aws-glue-programming-etl-format-orc-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 ORC 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 ORC 형식 사용을 지원합니다. 이 형식은 성능 중심의 열 기반 데이터 형식입니다. 표준 기관의 형식에 대한 소개는 [Apache Orc](https://orc.apache.org/docs/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3와 스트리밍 소스에서 ORC 파일을 읽을 수 있을 뿐만 아니라 Amazon S3에 ORC 파일을 쓸 수 있습니다. S3에서 ORC 파일이 포함된 `bzip` 및 `gzip` 아카이브를 읽고 쓸 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.

다음 표에서는 ORC 형식 옵션을 지원하는 일반적인 AWS Glue 기능을 보여 줍니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원 | 지원 | 지원되지 않음 | 지원\$1 | 

\$1 AWS Glue 버전 1.0 이상에서 지원

## 예: S3에서 ORC 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-orc-read"></a>

** 사전 조건:** 읽으려는 ORC 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

**구성:** 함수 옵션에서 `format="orc"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 리더와 S3가 상호 작용하는 방식을 구성할 수 있습니다. 자세한 내용은 AWS Glue에서 ETL 관련 연결 유형 및 옵션 참조: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)

 다음 AWS Glue ETL 스크립트는 S3에서 ORC 파일 또는 폴더를 읽는 프로세스를 보여 줍니다.

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

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="orc"
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read\
    .orc("s3://s3path")
```

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

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.sql.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      connectionType="s3",
      format="orc",
      options=JsonOptions("""{"paths": ["s3://s3path"]}""")
    ).getDynamicFrame()
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
val dataFrame = spark.read
    .orc("s3://s3path")
```

------

## 예: S3에 ORC 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-orc-write"></a>

**사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

**구성:** 함수 옵션에서 `format="orc"`를 지정합니다. 연결 옵션에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 라이터가 S3와 상호 작용하는 방식을 추가로 변경할 수 있습니다. 자세한 내용은 AWS Glue: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 입력 및 출력에 대한 데이터 형식 옵션을 참조하세요. 다음 코드 예제는 프로세스를 보여 줍니다.

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

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    format="orc",
    connection_options={
        "path": "s3://s3path"
    }
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.orc("s3://s3path/")
```

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

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    glueContext.getSinkWithFormat(
      connectionType="s3",
      options=JsonOptions("""{"path": "s3://s3path"}"""),
      format="orc"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.orc("s3://s3path/")
```

------

## XML 구성 참조
<a name="aws-glue-programming-etl-format-orc-reference"></a>

`format="orc"`을 위한 `format_options` 값은 없습니다. 그러나 SparkSQL 기초 코드에 의해 수락된 옵션은 `connection_options` 맵 파라미터를 거쳐 SparkSQL 기초 코드로 넘겨질 수 있습니다.

# AWS Glue ETL 작업에서 데이터 레이크 프레임워크 사용
<a name="aws-glue-programming-etl-datalake-native-frameworks"></a>

오픈 소스 데이터 레이크 프레임워크는 Amazon S3에 빌드된 데이터 레이크에 저장된 파일의 증분 데이터 처리를 간소화합니다. AWS Glue 3.0 이상에서는 다음과 같은 오픈 소스 데이터 레이크 프레임워크를 지원합니다.
+ Apache Hudi
+ Linux Foundation Delta Lake
+ Apache Iceberg

Amazon S3에 저장된 데이터를 트랜잭션적으로 일관된 방식으로 읽고 쓸 수 있도록 이러한 프레임워크에 대한 기본 지원을 제공합니다. AWS Glue ETL 작업에 이러한 프레임워크를 사용하기 위해 별도의 커넥터를 설치하거나 추가 구성 단계를 완료할 필요가 없습니다.

AWS Glue Data Catalog를 통해 데이터 세트를 관리하는 경우 Spark DataFrames에서 AWS Glue 메서드를 사용하여 데이터 레이크 테이블을 읽고 쓸 수 있습니다. Spark DataFrame API를 사용하여 Amazon S3 데이터를 읽고 쓸 수도 있습니다.

이 비디오에서는 Apache Hudi, Apache Iceberg 및 Delta Lake work의 작동 방식에 대한 기본 사항을 살펴봅니다. 데이터 레이크에서 데이터를 삽입, 업데이트 및 삭제하는 방법과 각 프레임워크의 작동 방식을 확인할 수 있습니다.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/fryfx0Zg7KA/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/fryfx0Zg7KA)


**Topics**
+ [제한 사항](aws-glue-programming-etl-datalake-native-frameworks-limitations.md)
+ [AWS Glue에서 Hudi 프레임워크 사용](aws-glue-programming-etl-format-hudi.md)
+ [AWS Glue에서 Delta Lake 프레임워크 사용](aws-glue-programming-etl-format-delta-lake.md)
+ [AWS Glue에서 Iceberg 프레임워크 사용](aws-glue-programming-etl-format-iceberg.md)

# 제한 사항
<a name="aws-glue-programming-etl-datalake-native-frameworks-limitations"></a>

AWS Glue에서 데이터 레이크 프레임워크를 사용하기 전에 다음 제한 사항을 고려하세요.
+ 다음 DynamicFrame의 AWS Glue `GlueContext` 방법은 데이터 레이크 프레임워크 테이블의 읽기 및 쓰기를 지원하지 않습니다. 대신 DataFrame 또는 Spark DataFrame API용 `GlueContext` 방법을 사용하십시오.
  + `create_dynamic_frame.from_catalog`
  + `write_dynamic_frame.from_catalog`
  + `getDynamicFrame`
  + `writeDynamicFrame`
+ Lake Formation 권한 제어에서는 다음과 같은 DataFrame `GlueContext` 방법이 지원됩니다.
  + `create_data_frame.from_catalog`
  + `write_data_frame.from_catalog`
  + `getDataFrame`
  + `writeDataFrame`
+ [작은 파일 그룹화](grouping-input-files.md)는 지원되지 않습니다.
+ [작업 북마크](monitor-continuations.md)는 지원되지 않습니다.
+ Apache Hudi 0.10.1 for AWS Glue 3.0은 Hudi 읽을 때 병합(MoR) 테이블을 지원하지 않습니다.
+ `ALTER TABLE … RENAME TO`는 Apache Iceberg 0.13.1 for AWS Glue 3.0에서 사용할 수 없습니다.

## Lake Formation 권한으로 관리되는 데이터 레이크 형식 테이블에 대한 제한
<a name="w2aac67c11c24c11c31c17b7"></a>

데이터 레이크 형식은 Lake Formation 권한을 통해 AWS Glue ETL과 통합됩니다. `create_dynamic_frame`를 사용하여 DynamicFrame을 생성하는 것은 지원되지 않습니다. 자세한 내용은 다음 예를 참조하세요.
+ [예: Lake Formation 권한 제어가 포함된 Iceberg 테이블 읽기 및 쓰기](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-format-iceberg.html#aws-glue-programming-etl-format-iceberg-read-write-lake-formation-tables)
+ [예: Lake Formation 권한 제어를 사용하여 Hudi 테이블 읽기 및 쓰기](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-format-hudi.html#aws-glue-programming-etl-format-hudi-read-write-lake-formation-tables)
+ [예: Lake Formation 권한 제어가 포함된 Delta Lake 테이블 읽기 및 쓰기](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-format-delta-lake.html#aws-glue-programming-etl-format-delta-lake-read-write-lake-formation-tables)

**참고**  
Apache Hudi, Apache Iceberg, Delta Lake에 대한 Lake Formation 권한을 통한 AWS Glue ETL과의 통합은 AWS Glue 버전 4.0에서만 지원됩니다.

Apache Iceberg는 Lake Formation 권한을 통해 AWS Glue ETL과 가장 잘 통합됩니다. 거의 모든 작업을 지원하며 SQL 지원을 포함합니다.

Hudi는 관리 작업을 제외한 대부분의 기본 작업을 지원합니다. 이러한 옵션은 일반적으로 데이터 프레임 작성을 통해 수행되고 `additional_options`를 통해 지정되기 때문입니다. SparkSQL은 지원되지 않으므로 AWS Glue API를 사용하여 작업을 위한 DataFrames을 생성해야 합니다.

Delta Lake는 테이블 데이터의 읽기, 추가, 덮어쓰기만 지원합니다. Delta Lake에서는 업데이트와 같은 다양한 작업을 수행하려면 자체 라이브러리를 사용해야 합니다.

Lake Formation 권한으로 관리되는 Iceberg 테이블에는 다음 기능을 사용할 수 없습니다.
+ AWS Glue ETL을 사용한 압축
+ AWS Glue ETL을 통한 Spark SQL 지원

Lake Formation 권한으로 관리되는 Hudi 테이블의 제한 사항은 다음과 같습니다.
+ 분리된 파일 제거

Lake Formation 권한으로 관리되는 Delta Lake 테이블의 제한 사항은 다음과 같습니다.
+ Delta Lake 테이블에서 삽입 및 읽기 이외의 모든 기능.

# AWS Glue에서 Hudi 프레임워크 사용
<a name="aws-glue-programming-etl-format-hudi"></a>

AWS Glue 3.0 이상에서는 데이터 레이크에 대한 Apache Hudi 프레임워크를 지원합니다. Hudi는 증분 데이터 처리 및 데이터 파이프라인 개발을 간소화하는 오픈 소스 데이터 레이크 스토리지 프레임워크입니다. 이 항목에서는 Hudi 테이블에서 데이터를 전송하거나 저장할 때 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능에 대해 설명합니다. Hudi에 대한 자세한 내용은 공식 [Apache Hudi 설명서](https://hudi.apache.org/docs/overview/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3의 Hudi 테이블에서 읽기 및 쓰기 작업을 수행하거나 AWS Glue 데이터 카탈로그를 사용하여 Hudi 테이블로 작업할 수 있습니다. 삽입, 업데이트, 모든 [Apache Spark 작업](https://hudi.apache.org/docs/quick-start-guide/)을 포함한 추가 작업도 지원됩니다.

**참고**  
AWS Glue 5.0의 Apache Hudi 0.15.0 구현은 [HUDI-7001](https://github.com/apache/hudi/pull/9936)을 내부적으로 되돌립니다. 레코드 키가 단일 필드로 구성된 경우 복합 키 생성과 관련된 회귀를 나타내지 않습니다. 그러나 이 동작은 OSS Apache Hudi 0.15.0과 다릅니다.  
Apache Hudi 0.10.1 for AWS Glue 3.0은 Hudi 읽을 때 병합(MoR) 테이블을 지원하지 않습니다.

다음 표에는 각 AWS Glue 버전에 포함된 Hudi 버전이 나와 있습니다.


****  

| AWS Glue 버전 | 지원되는 Hudi 버전 | 
| --- | --- | 
| 5.1 | 1.0.2 | 
| 5.0 | 0.15.0 | 
| 4.0 | 0.12.1 | 
| 3.0 | 0.10.1 | 

AWS Glue가 지원하는 데이터 레이크 프레임워크에 대한 자세한 내용은 [AWS Glue ETL 작업에서 데이터 레이크 프레임워크 사용](aws-glue-programming-etl-datalake-native-frameworks.md) 섹션을 참조하세요.

## Hudi 활성화
<a name="aws-glue-programming-etl-format-hudi-enable"></a>

Hudi for AWS Glue를 활성화하려면 다음 작업을 완료합니다.
+ `hudi`를 `--datalake-formats` 작업 파라미터의 값으로 지정합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md) 섹션을 참조하세요.
+ AWS Glue 작업에 대한 `--conf` 키를 생성하고 다음 값으로 설정합니다. 또는 스크립트에서 `SparkConf`를 사용하여 다음 구성을 설정할 수 있습니다. 이러한 설정은 Apache Spark에서 Hudi 테이블을 올바르게 처리하는 데 도움이 됩니다.

  ```
  spark.serializer=org.apache.spark.serializer.KryoSerializer
  ```
+ Hudi에 대한 Lake Formation 권한 지원은 AWS Glue 4.0에서 기본으로 활성화되어 있습니다. Lake Formation에 등록된 Hudi 테이블을 읽고 쓰는 데 추가 구성이 필요하지 않습니다. 등록된 Hudi 테이블을 읽으려면 AWS Glue 작업 IAM 역할에 SELECT 권한이 있어야 합니다. 등록된 Hudi 테이블에 글을 쓰려면 AWS Glue 작업 IAM 역할에 SUPER 권한이 있어야 합니다. Lake Formation 권한 관리에 대해 자세히 알아보려면 [Data Catalog 리소스에 대한 권한 부여 및 취소](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)를 참조하십시오.

**다른 Hudi 버전 사용**

AWS Glue에서 지원하지 않는 Hudi 버전을 사용하려면 `--extra-jars` 작업 파라미터를 사용하여 고유한 Hudi JAR 파일을 지정하세요. `--datalake-formats` 작업 파라미터의 값으로 `hudi`를 포함하지 마세요. AWS Glue 5.0 이상을 사용하는 경우, `--user-jars-first true` 작업 파라미터를 설정해야 합니다.

## 예: Amazon S3에 Hudi 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록
<a name="aws-glue-programming-etl-format-hudi-write"></a>

이 예제 스크립트는 Amazon S3에 Hudi 테이블을 작성하고 AWS Glue 데이터 카탈로그에 테이블을 등록하는 방법을 보여줍니다. 이 예제에서는 Hudi [Hive Sync 도구](https://hudi.apache.org/docs/syncing_metastore/)를 사용하여 테이블을 등록합니다.

**참고**  
이 예에서는 AWS Glue 데이터 카탈로그를 Apache Spark Hive 메타스토어로 사용하기 위해 `--enable-glue-datacatalog` 작업 파라미터를 설정해야 합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md)를 참조하세요.

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

```
# Example: Create a Hudi table from a DataFrame 
# and register the table to Glue Data Catalog

additional_options={
    "hoodie.table.name": "<your_table_name>",
    "hoodie.database.name": "<your_database_name>",
    "hoodie.datasource.write.storage.type": "COPY_ON_WRITE",
    "hoodie.datasource.write.operation": "upsert",
    "hoodie.datasource.write.recordkey.field": "<your_recordkey_field>",
    "hoodie.datasource.write.precombine.field": "<your_precombine_field>",
    "hoodie.datasource.write.partitionpath.field": "<your_partitionkey_field>",
    "hoodie.datasource.write.hive_style_partitioning": "true",
    "hoodie.datasource.hive_sync.enable": "true",
    "hoodie.datasource.hive_sync.database": "<your_database_name>",
    "hoodie.datasource.hive_sync.table": "<your_table_name>",
    "hoodie.datasource.hive_sync.partition_fields": "<your_partitionkey_field>",
    "hoodie.datasource.hive_sync.partition_extractor_class": "org.apache.hudi.hive.MultiPartKeysValueExtractor",
    "hoodie.datasource.hive_sync.use_jdbc": "false",
    "hoodie.datasource.hive_sync.mode": "hms",
    "path": "s3://<s3Path/>"
}

dataFrame.write.format("hudi") \
    .options(**additional_options) \
    .mode("overwrite") \
    .save()
```

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

```
// Example: Example: Create a Hudi table from a DataFrame
// and register the table to Glue Data Catalog

val additionalOptions = Map(
  "hoodie.table.name" -> "<your_table_name>",
  "hoodie.database.name" -> "<your_database_name>",
  "hoodie.datasource.write.storage.type" -> "COPY_ON_WRITE",
  "hoodie.datasource.write.operation" -> "upsert",
  "hoodie.datasource.write.recordkey.field" -> "<your_recordkey_field>",
  "hoodie.datasource.write.precombine.field" -> "<your_precombine_field>",
  "hoodie.datasource.write.partitionpath.field" -> "<your_partitionkey_field>",
  "hoodie.datasource.write.hive_style_partitioning" -> "true",
  "hoodie.datasource.hive_sync.enable" -> "true",
  "hoodie.datasource.hive_sync.database" -> "<your_database_name>",
  "hoodie.datasource.hive_sync.table" -> "<your_table_name>",
  "hoodie.datasource.hive_sync.partition_fields" -> "<your_partitionkey_field>",
  "hoodie.datasource.hive_sync.partition_extractor_class" -> "org.apache.hudi.hive.MultiPartKeysValueExtractor",
  "hoodie.datasource.hive_sync.use_jdbc" -> "false",
  "hoodie.datasource.hive_sync.mode" -> "hms",
  "path" -> "s3://<s3Path/>")

dataFrame.write.format("hudi")
  .options(additionalOptions)
  .mode("append")
  .save()
```

------

## 예: AWS Glue 데이터 카탈로그를 사용하여 Amazon S3에서 Hudi 테이블 읽기
<a name="aws-glue-programming-etl-format-hudi-read"></a>

이 예에서는 Amazon S3의 [예: Amazon S3에 Hudi 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-hudi-write)에서 생성한 Hudi 테이블을 읽습니다.

**참고**  
이 예에서는 AWS Glue 데이터 카탈로그를 Apache Spark Hive 메타스토어로 사용하기 위해 `--enable-glue-datacatalog` 작업 파라미터를 설정해야 합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md)를 참조하세요.

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

이 예에서는 `GlueContext.create\$1data\$1frame.from\$1catalog()` 메서드를 사용합니다.

```
# Example: Read a Hudi table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

dataFrame = glueContext.create_data_frame.from_catalog(
    database = "<your_database_name>",
    table_name = "<your_table_name>"
)
```

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

이 예에서는 [getCatalogSource](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSource) 메서드를 사용합니다.

```
// Example: Read a Hudi table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    
    val dataFrame = glueContext.getCatalogSource(
      database = "<your_database_name>",
      tableName = "<your_table_name>"
    ).getDataFrame()
  }
}
```

------

## 예: Amazon S3의 Hudi 테이블에서 `DataFrame` 업데이트 및 삽입
<a name="aws-glue-programming-etl-format-hudi-update-insert"></a>

이 예제에서는 AWS Glue 데이터 카탈로그를 사용하여 [예: Amazon S3에 Hudi 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-hudi-write)에서 생성한 Hudi 테이블에 DataFrame을 삽입합니다.

**참고**  
이 예에서는 AWS Glue 데이터 카탈로그를 Apache Spark Hive 메타스토어로 사용하기 위해 `--enable-glue-datacatalog` 작업 파라미터를 설정해야 합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md)를 참조하세요.

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

이 예에서는 `GlueContext.write\$1data\$1frame.from\$1catalog()` 메서드를 사용합니다.

```
# Example: Upsert a Hudi table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

glueContext.write_data_frame.from_catalog(
    frame = dataFrame,
    database = "<your_database_name>",
    table_name = "<your_table_name>",
    additional_options={
        "hoodie.table.name": "<your_table_name>",
        "hoodie.database.name": "<your_database_name>",
        "hoodie.datasource.write.storage.type": "COPY_ON_WRITE",
        "hoodie.datasource.write.operation": "upsert",
        "hoodie.datasource.write.recordkey.field": "<your_recordkey_field>",
        "hoodie.datasource.write.precombine.field": "<your_precombine_field>",
        "hoodie.datasource.write.partitionpath.field": "<your_partitionkey_field>",
        "hoodie.datasource.write.hive_style_partitioning": "true",
        "hoodie.datasource.hive_sync.enable": "true",
        "hoodie.datasource.hive_sync.database": "<your_database_name>",
        "hoodie.datasource.hive_sync.table": "<your_table_name>",
        "hoodie.datasource.hive_sync.partition_fields": "<your_partitionkey_field>",
        "hoodie.datasource.hive_sync.partition_extractor_class": "org.apache.hudi.hive.MultiPartKeysValueExtractor",
        "hoodie.datasource.hive_sync.use_jdbc": "false",
        "hoodie.datasource.hive_sync.mode": "hms"
    }
)
```

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

이 예에서는 [getCatalogSink](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSink) 메서드를 사용합니다.

```
// Example: Upsert a Hudi table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import com.amazonaws.services.glue.util.JsonOptions
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    glueContext.getCatalogSink("<your_database_name>", "<your_table_name>",
      additionalOptions = JsonOptions(Map(
        "hoodie.table.name" -> "<your_table_name>",
        "hoodie.database.name" -> "<your_database_name>",
        "hoodie.datasource.write.storage.type" -> "COPY_ON_WRITE",
        "hoodie.datasource.write.operation" -> "upsert",
        "hoodie.datasource.write.recordkey.field" -> "<your_recordkey_field>",
        "hoodie.datasource.write.precombine.field" -> "<your_precombine_field>",
        "hoodie.datasource.write.partitionpath.field" -> "<your_partitionkey_field>",
        "hoodie.datasource.write.hive_style_partitioning" -> "true",
        "hoodie.datasource.hive_sync.enable" -> "true",
        "hoodie.datasource.hive_sync.database" -> "<your_database_name>",
        "hoodie.datasource.hive_sync.table" -> "<your_table_name>",
        "hoodie.datasource.hive_sync.partition_fields" -> "<your_partitionkey_field>",
        "hoodie.datasource.hive_sync.partition_extractor_class" -> "org.apache.hudi.hive.MultiPartKeysValueExtractor",
        "hoodie.datasource.hive_sync.use_jdbc" -> "false",
        "hoodie.datasource.hive_sync.mode" -> "hms"
      )))
      .writeDataFrame(dataFrame, glueContext)
  }
}
```

------

## 예: Spark를 사용하여 Amazon S3에서 Hudi 테이블 읽기
<a name="aws-glue-programming-etl-format-hudi-read-spark"></a>

이 예에서는 Spark DataFrame API를 사용하여 Amazon S3에서 Hudi 테이블을 읽습니다.

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

```
# Example: Read a Hudi table from S3 using a Spark DataFrame

dataFrame = spark.read.format("hudi").load("s3://<s3path/>")
```

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

```
// Example: Read a Hudi table from S3 using a Spark DataFrame

val dataFrame = spark.read.format("hudi").load("s3://<s3path/>")
```

------

## 예: Spark를 사용하여 Amazon S3에 Hudi 테이블 쓰기
<a name="aws-glue-programming-etl-format-hudi-write-spark"></a>

이 예에서는 Spark를 사용하여 Amazon S3에 Hudi 테이블을 씁니다.

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

```
# Example: Write a Hudi table to S3 using a Spark DataFrame

dataFrame.write.format("hudi") \
    .options(**additional_options) \
    .mode("overwrite") \
    .save("s3://<s3Path/>)
```

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

```
// Example: Write a Hudi table to S3 using a Spark DataFrame

dataFrame.write.format("hudi")
  .options(additionalOptions)
  .mode("overwrite")
  .save("s3://<s3path/>")
```

------

## 예: Lake Formation 권한 제어를 사용하여 Hudi 테이블 읽기 및 쓰기
<a name="aws-glue-programming-etl-format-hudi-read-write-lake-formation-tables"></a>

이 예제에서는 Lake Formation 권한 제어가 있는 Hudi 테이블을 읽고 씁니다.

1. Hudi 테이블을 생성하여 Lake Formation에 등록합니다.

   1. Lake Formation 권한 제어를 활성화하려면 먼저 Lake Formation에 Amazon S3 경로를 등록해야 합니다. 자세한 내용을 알아보려면 [Registering an Amazon S3 location](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html)(Amazon S3 위치 등록)을 참조하세요. Lake Formation 콘솔에서 등록하거나 AWS CLI를 사용하여 등록할 수 있습니다.

      ```
      aws lakeformation register-resource --resource-arn arn:aws:s3:::<s3-bucket>/<s3-folder> --use-service-linked-role --region <REGION>
      ```

      Amazon S3 위치를 등록하면 해당 위치(또는 하위 위치)를 가리키는 AWS Glue 테이블이 `GetTable` 호출 시 `IsRegisteredWithLakeFormation` 파라미터 값을 true로 반환합니다.

   1. Spark 데이터프레임 API를 통해 등록된 Amazon S3 경로를 가리키는 Hudi 테이블을 생성합니다.

      ```
      hudi_options = {
          'hoodie.table.name': table_name,
          'hoodie.database.name': database_name,
          'hoodie.datasource.write.storage.type': 'COPY_ON_WRITE',
          'hoodie.datasource.write.recordkey.field': 'product_id',
          'hoodie.datasource.write.table.name': table_name,
          'hoodie.datasource.write.operation': 'upsert',
          'hoodie.datasource.write.precombine.field': 'updated_at',
          'hoodie.datasource.write.hive_style_partitioning': 'true',
          'hoodie.upsert.shuffle.parallelism': 2,
          'hoodie.insert.shuffle.parallelism': 2,
          'path': <S3_TABLE_LOCATION>,
          'hoodie.datasource.hive_sync.enable': 'true',
          'hoodie.datasource.hive_sync.database': database_name,
          'hoodie.datasource.hive_sync.table': table_name,
          'hoodie.datasource.hive_sync.use_jdbc': 'false',
          'hoodie.datasource.hive_sync.mode': 'hms'
      }
      
      df_products.write.format("hudi")  \
          .options(**hudi_options)  \
          .mode("overwrite")  \
          .save()
      ```

1. AWSGlue 작업 IAM 역할에 Lake Formation 권한을 부여하십시오. Lake Formation 콘솔에서 권한을 부여하거나 AWS CLI를 사용하여 권한을 부여할 수 있습니다. 자세한 내용을 알아보려면 [Lake Formation 콘솔 및 명명된 리소스 방법을 사용하여 데이터베이스 권한 부여](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-table-permissions.html)를 참조하십시오

1.  Lake Formation에 등록된 Hudi 테이블을 읽어보십시오. 코드는 등록되지 않은 Hudi 테이블을 읽는 것과 같습니다. 읽기에 성공하려면 AWS Glue 작업 IAM 역할에 SELECT 권한이 있어야 한다는 점에 유의하십시오.

   ```
    val dataFrame = glueContext.getCatalogSource(
         database = "<your_database_name>",
         tableName = "<your_table_name>"
       ).getDataFrame()
   ```

1. Lake Formation에 등록된 Hudi 테이블에 글을 작성하십시오. 코드는 등록되지 않은 Hudi 테이블에 쓰는 것과 같습니다. 참고로 AWS Glue 작업 IAM 역할에 SUPER 권한이 있어야 쓰기가 성공합니다.

   ```
   glueContext.getCatalogSink("<your_database_name>", "<your_table_name>",
         additionalOptions = JsonOptions(Map(
           "hoodie.table.name" -> "<your_table_name>",
           "hoodie.database.name" -> "<your_database_name>",
           "hoodie.datasource.write.storage.type" -> "COPY_ON_WRITE",
           "hoodie.datasource.write.operation" -> "<write_operation>",
           "hoodie.datasource.write.recordkey.field" -> "<your_recordkey_field>",
           "hoodie.datasource.write.precombine.field" -> "<your_precombine_field>",
           "hoodie.datasource.write.partitionpath.field" -> "<your_partitionkey_field>",
           "hoodie.datasource.write.hive_style_partitioning" -> "true",
           "hoodie.datasource.hive_sync.enable" -> "true",
           "hoodie.datasource.hive_sync.database" -> "<your_database_name>",
           "hoodie.datasource.hive_sync.table" -> "<your_table_name>",
           "hoodie.datasource.hive_sync.partition_fields" -> "<your_partitionkey_field>",
           "hoodie.datasource.hive_sync.partition_extractor_class" -> "org.apache.hudi.hive.MultiPartKeysValueExtractor",
           "hoodie.datasource.hive_sync.use_jdbc" -> "false",
           "hoodie.datasource.hive_sync.mode" -> "hms"
         )))
         .writeDataFrame(dataFrame, glueContext)
   ```

# AWS Glue에서 Delta Lake 프레임워크 사용
<a name="aws-glue-programming-etl-format-delta-lake"></a>

AWS Glue 3.0 이상은 Linux Foundation Delta Lake 프레임워크를 지원합니다. Delta Lake는 ACID 트랜잭션을 수행하고, 메타데이터 처리를 확장하고, 스트리밍 및 배치 데이터 처리를 통합하는 데 도움이 되는 오픈 소스 데이터 레이크 스토리지 프레임워크입니다. 이 항목에서는 Delta Lake 테이블에서 데이터를 전송하거나 저장할 때 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능에 대해 설명합니다. Delta Lake에 대한 자세한 내용은 공식 [Delta Lake 설명서](https://docs.delta.io/latest/delta-intro.html)를 참조하세요.

AWS Glue를 사용하여 Amazon S3의 Delta Lake 테이블에서 읽기 및 쓰기 작업을 수행하거나 AWS Glue 데이터 카탈로그를 사용하여 Delta Lake 테이블로 작업할 수 있습니다. 삽입, 업데이트, [테이블 배치 읽기 및 쓰기](https://docs.delta.io/0.7.0/api/python/index.html)와 같은 추가 작업도 지원됩니다. Delta Lake 테이블을 사용할 경우 Delta Lake Python 라이브러리(예: `DeltaTable.forPath`)의 메서드를 사용할 수도 있습니다. Delta Lake Python 라이브러리에 대한 자세한 내용은 Delta Lake의 Python 설명서를 참조하세요.

다음 표에는 각 AWS Glue 버전에 포함된 Delta Lake의 버전이 나와 있습니다.


****  

| AWS Glue 버전 | 지원되는 Delta Lake 버전 | 
| --- | --- | 
| 5.1 | 3.3.2 | 
| 5.0 | 3.3.0 | 
| 4.0 | 2.1.0 | 
| 3.0 | 1.0.0 | 

AWS Glue가 지원하는 데이터 레이크 프레임워크에 대한 자세한 내용은 [AWS Glue ETL 작업에서 데이터 레이크 프레임워크 사용](aws-glue-programming-etl-datalake-native-frameworks.md) 섹션을 참조하세요.

## Delta Lake for AWS Glue 활성화
<a name="aws-glue-programming-etl-format-delta-lake-enable"></a>

Delta Lake for AWS Glue를 활성화하려면 다음 작업을 완료합니다.
+ `delta`를 `--datalake-formats` 작업 파라미터의 값으로 지정합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md) 섹션을 참조하세요.
+ AWS Glue 작업에 대한 `--conf` 키를 생성하고 다음 값으로 설정합니다. 또는 스크립트에서 `SparkConf`를 사용하여 다음 구성을 설정할 수 있습니다. 이러한 설정은 Apache Spark에서 Delta Lake 테이블을 올바르게 처리하는 데 도움이 됩니다.

  ```
  spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog --conf spark.delta.logStore.class=org.apache.spark.sql.delta.storage.S3SingleDriverLogStore
  ```
+ Delta 테이블에 대한 Lake Formation 권한 지원은 AWS Glue 4.0에서 기본적으로 활성화되어 있습니다. Lake Formation에 등록된 Delta 테이블을 읽고 쓰는 데 추가 구성이 필요하지 않습니다. 등록된 Delta 테이블을 읽으려면 AWS Glue 작업 IAM 역할에 SELECT 권한이 있어야 합니다. 등록된 Delta 테이블에 쓰려면 AWS Glue 작업 IAM 역할에 SUPER 권한이 있어야 합니다. Lake Formation 권한 관리에 대해 자세히 알아보려면 [Data Catalog 리소스에 대한 권한 부여 및 취소](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)를 참조하십시오.

**다른 Delta Lake 버전 사용**

AWS Glue에서 지원하지 않는 Delta Lake 버전을 사용하려면 `--extra-jars` 작업 파라미터를 사용하여 고유한 Delta Lake JAR 파일을 지정하세요. `--datalake-formats` 작업 파라미터의 값으로 `delta`를 포함하지 마세요. AWS Glue 5.0 이상을 사용하는 경우, `--user-jars-first true` 작업 파라미터를 설정해야 합니다. 이 경우에 Delta Lake Python 라이브러리를 사용하려면 `--extra-py-files` 작업 파라미터를 사용하여 라이브러리 JAR 파일을 지정해야 합니다. Python 라이브러리는 Delta Lake JAR 파일에 패키징되어 제공됩니다.

## 예: Amazon S3에 Delta Lake 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록
<a name="aws-glue-programming-etl-format-delta-lake-write"></a>

다음 AWS Glue ETL 스크립트는 Amazon S3에 Delta Lake 테이블을 작성하고 AWS Glue 데이터 카탈로그에 테이블을 등록하는 방법을 보여줍니다.

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

```
# Example: Create a Delta Lake table from a DataFrame 
# and register the table to Glue Data Catalog

additional_options = {
    "path": "s3://<s3Path>"
}
dataFrame.write \
    .format("delta") \
    .options(**additional_options) \
    .mode("append") \
    .partitionBy("<your_partitionkey_field>") \
    .saveAsTable("<your_database_name>.<your_table_name>")
```

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

```
// Example: Example: Create a Delta Lake table from a DataFrame
// and register the table to Glue Data Catalog

val additional_options = Map(
  "path" -> "s3://<s3Path>"
)
dataFrame.write.format("delta")
  .options(additional_options)
  .mode("append")
  .partitionBy("<your_partitionkey_field>")
  .saveAsTable("<your_database_name>.<your_table_name>")
```

------

## 예: AWS Glue 데이터 카탈로그를 사용하여 Amazon S3에서 Delta Lake 테이블 읽기
<a name="aws-glue-programming-etl-format-delta-lake-read"></a>

다음 AWS Glue ETL 스크립트는 [예: Amazon S3에 Delta Lake 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-delta-lake-write)에서 생성한 Delta Lake 테이블을 읽습니다.

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

이 예에서는 [create\$1data\$1frame.from\$1catalog](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create-dataframe-from-catalog) 메서드를 사용합니다.

```
# Example: Read a Delta Lake table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

df = glueContext.create_data_frame.from_catalog(
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

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

이 예에서는 [getCatalogSource](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSource) 메서드를 사용합니다.

```
// Example: Read a Delta Lake table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    val df = glueContext.getCatalogSource("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .getDataFrame()
  }
}
```

------

## 예: AWS Glue 데이터 카탈로그를 사용하여 Amazon S3에서 Delta Lake 테이블에 `DataFrame` 삽입
<a name="aws-glue-programming-etl-format-delta-lake-insert"></a>

이 예에서는 [예: Amazon S3에 Delta Lake 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-delta-lake-write)에서 생성한 Delta Lake 테이블에 데이터를 삽입합니다.

**참고**  
이 예에서는 AWS Glue 데이터 카탈로그를 Apache Spark Hive 메타스토어로 사용하기 위해 `--enable-glue-datacatalog` 작업 파라미터를 설정해야 합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md)를 참조하세요.

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

이 예에서는 [write\$1data\$1frame.from\$1catalog](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_data_frame_from_catalog) 메서드를 사용합니다.

```
# Example: Insert into a Delta Lake table in S3 using Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

glueContext.write_data_frame.from_catalog(
    frame=dataFrame,
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

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

이 예에서는 [getCatalogSink](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSink) 메서드를 사용합니다.

```
// Example: Insert into a Delta Lake table in S3 using Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    glueContext.getCatalogSink("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .writeDataFrame(dataFrame, glueContext)
  }
}
```

------

## 예: Spark API를 사용하여 Amazon S3에서 Delta Lake 테이블 읽기
<a name="aws-glue-programming-etl-format-delta_lake-read-spark"></a>

이 예에서는 Spark API를 사용하여 Amazon S3에서 Delta Lake 테이블을 읽습니다.

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

```
# Example: Read a Delta Lake table from S3 using a Spark DataFrame

dataFrame = spark.read.format("delta").load("s3://<s3path/>")
```

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

```
// Example: Read a Delta Lake table from S3 using a Spark DataFrame

val dataFrame = spark.read.format("delta").load("s3://<s3path/>")
```

------

## 예: Spark를 사용하여 Amazon S3에 Delta Lake 테이블 쓰기
<a name="aws-glue-programming-etl-format-delta_lake-write-spark"></a>

이 예에서는 Spark를 사용하여 Amazon S3에 Delta Lake 테이블을 씁니다.

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

```
# Example: Write a Delta Lake table to S3 using a Spark DataFrame

dataFrame.write.format("delta") \
    .options(**additional_options) \
    .mode("overwrite") \
    .partitionBy("<your_partitionkey_field>")
    .save("s3://<s3Path>")
```

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

```
// Example: Write a Delta Lake table to S3 using a Spark DataFrame

dataFrame.write.format("delta")
  .options(additionalOptions)
  .mode("overwrite")
  .partitionBy("<your_partitionkey_field>")
  .save("s3://<s3path/>")
```

------

## 예: Lake Formation 권한 제어가 포함된 Delta Lake 테이블 읽기 및 쓰기
<a name="aws-glue-programming-etl-format-delta-lake-read-write-lake-formation-tables"></a>

이 예제에서는 Lake Formation 권한 제어를 사용하여 Delta Lake 테이블을 읽고 씁니다.

1. Delta 테이블을 생성하여 Lake Formation에 등록하기

   1. Lake Formation 권한 제어를 활성화하려면 먼저 Lake Formation에 Amazon S3 경로를 등록해야 합니다. 자세한 내용을 알아보려면 [Registering an Amazon S3 location](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html)(Amazon S3 위치 등록)을 참조하세요. Lake Formation 콘솔에서 등록하거나 AWS CLI를 사용하여 등록할 수 있습니다.

      ```
      aws lakeformation register-resource --resource-arn arn:aws:s3:::<s3-bucket>/<s3-folder> --use-service-linked-role --region <REGION>
      ```

      Amazon S3 위치를 등록하면 해당 위치(또는 하위 위치)를 가리키는 AWS Glue 테이블이 `GetTable` 호출 시 `IsRegisteredWithLakeFormation` 파라미터 값을 true로 반환합니다.

   1. Spark를 통해 등록된 Amazon S3 경로를 가리키는 Delta 테이블을 생성합니다.
**참고**  
Python의 예를 들면 다음과 같습니다.

      ```
      dataFrame.write \
      	.format("delta") \
      	.mode("overwrite") \
      	.partitionBy("<your_partitionkey_field>") \
      	.save("s3://<the_s3_path>")
      ```

      Amazon S3에 데이터를 기록한 후 AWS Glue 크롤러를 사용하여 새 Delta 카탈로그 테이블을 생성합니다. 자세한 내용은 [AWSGlue 크롤러를 통한 네이티브 Delta Lake 테이블 지원 소개](https://aws.amazon.com/blogs/big-data/introducing-native-delta-lake-table-support-with-aws-glue-crawlers/)를 참조하십시오.

      AWSGlue `CreateTable` API를 통해 테이블을 수동으로 생성할 수도 있습니다.

1. AWSGlue 작업 IAM 역할에 Lake Formation 권한을 부여하십시오. Lake Formation 콘솔에서 권한을 부여하거나 AWS CLI를 사용하여 권한을 부여할 수 있습니다. 자세한 내용을 알아보려면 [Lake Formation 콘솔 및 명명된 리소스 방법을 사용하여 데이터베이스 권한 부여](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-table-permissions.html)를 참조하십시오

1.  Lake Formation에 등록된 Delta 테이블을 읽어보십시오. 코드는 등록되지 않은 Delta 테이블을 읽는 것과 같습니다. 읽기에 성공하려면 AWS Glue 작업 IAM 역할에 SELECT 권한이 있어야 한다는 점에 유의하십시오.

   ```
   # Example: Read a Delta Lake table from Glue Data Catalog
   
   df = glueContext.create_data_frame.from_catalog(
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```

1. Lake Formation에 등록된 Delta 테이블에 글을 씁니다. 코드는 등록되지 않은 Delta 테이블에 쓰는 것과 같습니다. 참고로 AWS Glue 작업 IAM 역할에 SUPER 권한이 있어야 쓰기가 성공합니다.

   기본 설정상 AWS Glue는 `Append`를 saveMode로 사용합니다. `additional_options`에서 saveMode 옵션을 설정하여 변경할 수 있습니다. Delta 테이블의 saveMode 지원에 대한 자세한 내용은 [테이블에 쓰기](https://docs.delta.io/latest/delta-batch.html#write-to-a-table)를 참조하십시오.

   ```
   glueContext.write_data_frame.from_catalog(
       frame=dataFrame,
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```

# AWS Glue에서 Iceberg 프레임워크 사용
<a name="aws-glue-programming-etl-format-iceberg"></a>

AWS Glue 3.0 이상에서는 데이터 레이크에 대한 Apache Iceberg 프레임워크를 지원합니다. Iceberg는 SQL 테이블처럼 작동하는 고성능 테이블 형식을 제공합니다. 이 항목에서는 Iceberg 테이블에서 데이터를 전송하거나 저장할 때 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능에 대해 설명합니다. Iceberg에 대한 자세한 내용은 공식 [Apache Iceberg 설명서](https://iceberg.apache.org/docs/latest/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3의 Iceberg 테이블에서 읽기 및 쓰기 작업을 수행하거나 AWS Glue 데이터 카탈로그를 사용하여 Iceberg 테이블로 작업할 수 있습니다. 삽입 및 모든 [Spark 쿼리](https://iceberg.apache.org/docs/latest/spark-queries/) [Spark 쓰기](https://iceberg.apache.org/docs/latest/spark-writes/)를 포함한 추가 작업도 지원됩니다. Iceberg 테이블에 대한 업데이트는 지원되지 않습니다.

**참고**  
`ALTER TABLE … RENAME TO`는 Apache Iceberg 0.13.1 for AWS Glue 3.0에서 사용할 수 없습니다.

다음 표에는 각 AWS Glue 버전에 포함된 Iceberg의 버전이 나와 있습니다.


****  

| AWS Glue 버전 | 지원되는 Iceberg 버전 | 
| --- | --- | 
| 5.1 | 1.10.0 | 
| 5.0 | 1.7.1 | 
| 4.0 | 1.0.0 | 
| 3.0 | 0.13.1 | 

AWS Glue가 지원하는 데이터 레이크 프레임워크에 대한 자세한 내용은 [AWS Glue ETL 작업에서 데이터 레이크 프레임워크 사용](aws-glue-programming-etl-datalake-native-frameworks.md) 섹션을 참조하세요.

## Iceberg 프레임워크 활성화
<a name="aws-glue-programming-etl-format-iceberg-enable"></a>

Iceberg for AWS Glue를 활성화하려면 다음 작업을 완료합니다.
+ `iceberg`를 `--datalake-formats` 작업 파라미터의 값으로 지정합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md) 섹션을 참조하세요.
+ AWS Glue 작업에 대한 `--conf` 키를 생성하고 다음 값으로 설정합니다. 또는 스크립트에서 `SparkConf`를 사용하여 다음 구성을 설정할 수 있습니다. 이러한 설정은 Apache Spark에서 Iceberg 테이블을 올바르게 처리하는 데 도움이 됩니다.

  ```
  spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions 
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog 
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://<your-warehouse-dir>/ 
  --conf spark.sql.catalog.glue_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
  --conf spark.sql.catalog.glue_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO
  ```

  Lake Formation에 등록된 Iceberg 테이블을 읽거나 쓰는 경우 AWS Glue 5.0 이상 [세분화된 액세스 제어를 위해 AWS Lake Formation과 함께 AWS Glue 사용](security-lf-enable.md)에서의 지침을 따르세요. AWS Glue 4.0에서 다음 구성을 추가하여 Lake Formation 지원을 활성화합니다.

  ```
  --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true
  --conf spark.sql.catalog.glue_catalog.glue.id=<table-catalog-id>
  ```

  AWS Glue 3.0을 Iceberg 0.13.1과 함께 사용하는 경우 Amazon DynamoDB 잠금 관리자를 사용하여 원자성 트랜잭션을 보장하려면 다음과 같은 추가 구성을 설정해야 합니다. AWS Glue 4.0 이상은 기본적으로 낙관적 잠금을 사용합니다. 자세한 내용은 공식 Apache Iceberg 설명서의 [Iceberg AWS 통합](https://iceberg.apache.org/docs/latest/aws/#dynamodb-lock-manager)을 참조하세요.

  ```
  --conf spark.sql.catalog.glue_catalog.lock-impl=org.apache.iceberg.aws.glue.DynamoLockManager 
  --conf spark.sql.catalog.glue_catalog.lock.table=<your-dynamodb-table-name>
  ```

**다른 Iceberg 버전 사용**

AWS Glue에서 지원하지 않는 Iceberg 버전을 사용하려면 `--extra-jars` 작업 파라미터를 사용하여 고유한 Iceberg JAR 파일을 지정하세요. `--datalake-formats` 파라미터의 값으로 `iceberg`를 포함하지 마세요. AWS Glue 5.0 이상을 사용하는 경우, `--user-jars-first true` 작업 파라미터를 설정해야 합니다.

**Iceberg 테이블에 대한 암호화 활성화**

**참고**  
Iceberg 테이블에는 서버 측 암호화를 활성화하는 자체 메커니즘이 있습니다. AWS Glue의 보안 구성 외에도 이 구성을 활성화해야 합니다.

Iceberg 테이블에서 서버 측 암호화를 활성화하려면 [Iceberg 설명서](https://iceberg.apache.org/docs/latest/aws/#s3-server-side-encryption)의 지침을 검토하세요.

**Iceberg 교차 리전에 대한 Spark 구성 추가**

AWS Glue Data Catalog 및 AWS Lake Formation을 사용하여 Iceberg 교차 리전 테이블 액세스에 대한 스파크 구성을 추가하려면 아래 단계를 따르세요.

1. [다중 리전 액세스 포인트](https://docs.aws.amazon.com/AmazonS3/latest/userguide/multi-region-access-point-create-examples.html)를 생성합니다.

1. 다음 Spark 속성을 설정합니다.

   ```
   -----
       --conf spark.sql.catalog.my_catalog.s3.use-arn-region-enabled=true \
       --conf spark.sql.catalog.{CATALOG}.s3.access-points.bucket1", "arn:aws:s3::<account-id>:accesspoint/<mrap-id>.mrap \
       --conf spark.sql.catalog.{CATALOG}.s3.access-points.bucket2", "arn:aws:s3::<account-id>:accesspoint/<mrap-id>.mrap
   -----
   ```

## 예: Amazon S3에 Iceberg 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록
<a name="aws-glue-programming-etl-format-iceberg-write"></a>

이 예제 스크립트는 Amazon S3에 Iceberg 테이블을 쓰는 방법을 보여줍니다. 이 예제에서는 [Iceberg AWS 통합](https://iceberg.apache.org/docs/latest/aws/)을 사용하여 테이블을 AWS Glue 데이터 카탈로그에 등록합니다.

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

```
# Example: Create an Iceberg table from a DataFrame 
# and register the table to Glue Data Catalog

dataFrame.createOrReplaceTempView("tmp_<your_table_name>")

query = f"""
CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
USING iceberg
TBLPROPERTIES ("format-version"="2")
AS SELECT * FROM tmp_<your_table_name>
"""
spark.sql(query)
```

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

```
// Example: Example: Create an Iceberg table from a DataFrame
// and register the table to Glue Data Catalog

dataFrame.createOrReplaceTempView("tmp_<your_table_name>")

val query = """CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
USING iceberg
TBLPROPERTIES ("format-version"="2")
AS SELECT * FROM tmp_<your_table_name>
"""
spark.sql(query)
```

------

대신에 Spark 메서드를 사용하여 Amazon S3 및 데이터 카탈로그에 Iceberg 테이블을 작성할 수 있습니다.

사전 조건: Iceberg 라이브러리에서 사용할 카탈로그를 프로비저닝해야 합니다. AWS Glue 데이터 카탈로그를 사용할 때 AWS Glue를 사용하면 이 작업을 간편하게 수행할 수 있습니다. AWS Glue 데이터 카탈로그는 Spark 라이브러리에서 `glue_catalog`로 사용하도록 미리 구성되어 있습니다. 데이터 카탈로그 테이블은 *databaseName* 및 *tableName*으로 식별됩니다. AWS Glue 데이터 카탈로그에 대한 자세한 내용은 [AWS Glue에서 데이터 검색 및 카탈로그 작성](catalog-and-crawler.md) 섹션을 참조하세요.

AWS Glue 데이터 카탈로그를 사용하지 않는 경우 Spark API를 통해 카탈로그를 프로비저닝해야 합니다. 자세한 내용은 Iceberg 설명서의 [Spark Configuration](https://iceberg.apache.org/docs/latest/spark-configuration/)을 참조하세요.

이 예시에서는 Spark를 사용하여 데이터 카탈로그에서 Amazon S3의 Iceberg 테이블을 작성합니다.

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

```
# Example: Write an Iceberg table to S3 on the Glue Data Catalog

# Create (equivalent to CREATE TABLE AS SELECT)
dataFrame.writeTo("glue_catalog.databaseName.tableName") \
    .tableProperty("format-version", "2") \
    .create()

# Append (equivalent to INSERT INTO)
dataFrame.writeTo("glue_catalog.databaseName.tableName") \
    .tableProperty("format-version", "2") \
    .append()
```

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

```
// Example: Write an Iceberg table to S3 on the Glue Data Catalog

// Create (equivalent to CREATE TABLE AS SELECT)
dataFrame.writeTo("glue_catalog.databaseName.tableName")
    .tableProperty("format-version", "2")
    .create()

// Append (equivalent to INSERT INTO)
dataFrame.writeTo("glue_catalog.databaseName.tableName")
    .tableProperty("format-version", "2")
    .append()
```

------

## 예: AWS Glue 데이터 카탈로그를 사용하여 Amazon S3에서 Iceberg 테이블 읽기
<a name="aws-glue-programming-etl-format-iceberg-read"></a>

이 예제에서는 [예: Amazon S3에 Iceberg 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-iceberg-write)에서 생성한 Iceberg 테이블을 읽습니다.

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

이 예에서는 `GlueContext.create\$1data\$1frame.from\$1catalog()` 메서드를 사용합니다.

```
# Example: Read an Iceberg table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

df = glueContext.create_data_frame.from_catalog(
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

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

이 예에서는 [getCatalogSource](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSource) 메서드를 사용합니다.

```
// Example: Read an Iceberg table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    val df = glueContext.getCatalogSource("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .getDataFrame()
  }
}
```

------

## 예: AWS Glue 데이터 카탈로그를 사용하여 Amazon S3에서 Iceberg 테이블에 `DataFrame` 삽입
<a name="aws-glue-programming-etl-format-iceberg-insert"></a>

이 예에서는 [예: Amazon S3에 Iceberg 테이블을 작성하고 AWS Glue 데이터 카탈로그에 등록](#aws-glue-programming-etl-format-iceberg-write)에서 생성한 Iceberg 테이블에 데이터를 삽입합니다.

**참고**  
이 예에서는 AWS Glue 데이터 카탈로그를 Apache Spark Hive 메타스토어로 사용하기 위해 `--enable-glue-datacatalog` 작업 파라미터를 설정해야 합니다. 자세한 내용은 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md)를 참조하세요.

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

이 예에서는 `GlueContext.write\$1data\$1frame.from\$1catalog()` 메서드를 사용합니다.

```
# Example: Insert into an Iceberg table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

glueContext.write_data_frame.from_catalog(
    frame=dataFrame,
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

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

이 예에서는 [getCatalogSink](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSink) 메서드를 사용합니다.

```
// Example: Insert into an Iceberg table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    glueContext.getCatalogSink("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .writeDataFrame(dataFrame, glueContext)
  }
}
```

------

## 예: Spark를 사용하여 Amazon S3에서 Iceberg 테이블 읽기
<a name="aws-glue-programming-etl-format-iceberg-read-spark"></a>

사전 조건: Iceberg 라이브러리에서 사용할 카탈로그를 프로비저닝해야 합니다. AWS Glue 데이터 카탈로그를 사용할 때 AWS Glue를 사용하면 이 작업을 간편하게 수행할 수 있습니다. AWS Glue 데이터 카탈로그는 Spark 라이브러리에서 `glue_catalog`로 사용하도록 미리 구성되어 있습니다. 데이터 카탈로그 테이블은 *databaseName* 및 *tableName*으로 식별됩니다. AWS Glue 데이터 카탈로그에 대한 자세한 내용은 [AWS Glue에서 데이터 검색 및 카탈로그 작성](catalog-and-crawler.md) 섹션을 참조하세요.

AWS Glue 데이터 카탈로그를 사용하지 않는 경우 Spark API를 통해 카탈로그를 프로비저닝해야 합니다. 자세한 내용은 Iceberg 설명서의 [Spark Configuration](https://iceberg.apache.org/docs/latest/spark-configuration/)을 참조하세요.

이 예제에서는 Spark를 사용하여 데이터 카탈로그에서 Amazon S3의 Iceberg 테이블을 읽습니다.

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

```
# Example: Read an Iceberg table on S3 as a DataFrame from the Glue Data Catalog

dataFrame = spark.read.format("iceberg").load("glue_catalog.databaseName.tableName")
```

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

```
// Example: Read an Iceberg table on S3 as a DataFrame from the Glue Data Catalog

val dataFrame = spark.read.format("iceberg").load("glue_catalog.databaseName.tableName")
```

------

## 예: Lake Formation 권한 제어가 포함된 Iceberg 테이블 읽기 및 쓰기
<a name="aws-glue-programming-etl-format-iceberg-read-write-lake-formation-tables"></a>

이 예제에서는 Lake Formation 권한 제어를 사용하여 Iceberg 테이블을 읽고 씁니다.

**참고**  
이 예제는 AWS Glue 4.0에서만 작동합니다. AWS Glue 5.0 이상에서는 [세분화된 액세스 제어를 위해 AWS Lake Formation과 함께 AWS Glue 사용](security-lf-enable.md)의 지침을 따릅니다.

1. Iceberg 테이블을 만들고 Lake Formation에 등록하십시오.

   1. Lake Formation 권한 제어를 활성화하려면 먼저 Lake Formation에 Amazon S3 경로를 등록해야 합니다. 자세한 내용을 알아보려면 [Registering an Amazon S3 location](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html)(Amazon S3 위치 등록)을 참조하세요. Lake Formation 콘솔에서 등록하거나 AWS CLI를 사용하여 등록할 수 있습니다.

      ```
      aws lakeformation register-resource --resource-arn arn:aws:s3:::<s3-bucket>/<s3-folder> --use-service-linked-role --region <REGION>
      ```

      Amazon S3 위치를 등록하면 해당 위치(또는 하위 위치)를 가리키는 AWS Glue 테이블이 `GetTable` 호출 시 `IsRegisteredWithLakeFormation` 파라미터 값을 true로 반환합니다.

   1. Spark SQL을 통해 등록된 경로를 가리키는 Iceberg 테이블을 생성하십시오.
**참고**  
Python의 예를 들면 다음과 같습니다.

      ```
      dataFrame.createOrReplaceTempView("tmp_<your_table_name>")
      
      query = f"""
      CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
      USING iceberg
      AS SELECT * FROM tmp_<your_table_name>
      """
      spark.sql(query)
      ```

      AWS Glue `CreateTable` API를 통해 테이블을 수동으로 생성할 수도 있습니다. 자세한 내용은 [Apache Iceberg 테이블 생성](https://docs.aws.amazon.com/lake-formation/latest/dg/creating-iceberg-tables.html)을 참조하십시오.
**참고**  
현재 `UpdateTable` API는 작업에 대한 입력으로 Iceberg 테이블 형식을 지원하지 않습니다.

1. 작업 IAM 역할에 Lake Formation 권한을 부여하십시오. Lake Formation 콘솔에서 권한을 부여하거나 AWS CLI를 사용하여 권한을 부여할 수 있습니다. 자세한 내용은 https://docs.aws.amazon.com/lake-formation/latest/dg/granting-table-permissions.html 단원을 참조하십시오.

1. Lake Formation에 등록된 Iceberg 테이블을 참조하십시오. 코드는 등록되지 않은 Iceberg 테이블을 읽는 것과 같습니다. 읽기에 성공하려면 AWS Glue Job IAM 역할에 SELECT 권한이 있어야 한다는 점에 유의하십시오.

   ```
   # Example: Read an Iceberg table from the AWS Glue Data Catalog
   from awsglue.context import GlueContextfrom pyspark.context import SparkContext
   
   sc = SparkContext()
   glueContext = GlueContext(sc)
   
   df = glueContext.create_data_frame.from_catalog(
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```

1. Lake Formation에 등록된 Iceberg 테이블에 씁니다. 코드는 등록되지 않은 Iceberg 테이블에 쓰는 것과 같습니다. 글쓰기가 성공하려면 AWS Glue 작업 IAM 역할에 SUPER 권한이 있어야 한다는 점을 참고하십시오.

   ```
   glueContext.write_data_frame.from_catalog(
       frame=dataFrame,
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```

## 공유 구성 참조
<a name="aws-glue-programming-etl-format-shared-reference"></a>

 모든 형식 유형의 다음과 같은 `format_options` 값을 사용할 수 있습니다.
+ `attachFilename` - 열 이름으로 사용할 적절한 형식의 문자열입니다. 이 옵션을 제공하면 레코드의 소스 파일 이름이 레코드에 추가됩니다. 파라미터 값이 열 이름으로 사용됩니다.
+ `attachTimestamp` - 열 이름으로 사용할 적절한 형식의 문자열입니다. 이 옵션을 제공하면 레코드의 소스 파일 수정 시간이 레코드에 추가됩니다. 파라미터 값이 열 이름으로 사용됩니다.