

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Delta Lake
<a name="emr-delta"></a>

Delta Lake는 일반적으로 Amazon S3에 구축되는 레이크 하우스 아키텍처를 위한 스토리지 계층 프레임워크입니다. Amazon EMR 릴리스 6.9.0 이상에서 Delta Lake 테이블을 포함하는 Amazon EMR 클러스터에서 [Apache Spark](https://aws.amazon.com/emr/features/spark/) 3.x를 사용할 수 있습니다. Delta Lake가 있는 레이크 하우스에 대한 자세한 내용은 [https://delta.io/](https://delta.io/)를 참조하세요.

다음 테이블에는 Amazon EMR이 Delta를 통해 설치하는 구성 요소와 함께 Amazon EMR 7.x 시리즈의 최신 릴리스에 포함된 Delta의 버전이 나열되어 있습니다.

이 릴리스에서 Delta와 함께 설치된 구성 요소의 버전은 [릴리스 7.12.0 구성 요소 버전을 참조하세요](emr-7120-release.md).


**emr-7.12.0용 델타 버전 정보**  

| Amazon EMR 릴리스 레이블 | Delta 버전 | Delta와 함께 설치된 구성 요소 | 
| --- | --- | --- | 
| emr-7.12.0 | Delta 3.3.2-amzn-1 | Not available. | 

다음 테이블에는 Amazon EMR이 Delta를 통해 설치하는 구성 요소와 함께 Amazon EMR 6.x 시리즈의 최신 릴리스에 포함된 Delta의 버전이 나열되어 있습니다.

이 릴리스에서 Delta와 함께 설치된 구성 요소의 버전은 [릴리스 6.15.0 구성 요소 버전](emr-6150-release.md)을 참조하세요.


**emr-6.15.0용 Delta 버전 정보**  

| Amazon EMR 릴리스 레이블 | Delta 버전 | Delta와 함께 설치된 구성 요소 | 
| --- | --- | --- | 
| emr-6.15.0 | Delta 2.4.0 | Not available. | 

# Delta Lake 소개
<a name="Deltaintro"></a>

Delta Lake는 Amazon S3에 일반적으로 구축되는 최신 데이터 레이크 아키텍처를 구현하는 데 도움이 되는 오픈 소스 프로젝트입니다. Delta Lake는 다음과 같은 기능을 제공합니다.
+ Spark에서의 원자성, 일관성, 격리성, 지속성(ACID) 지원 트랜잭션. 리더는 Spark 작업 중에 테이블의 일관된 보기를 봅니다.
+ Spark의 분산 처리를 통한 확장 가능한 메타데이터 처리.
+ 스트리밍 및 배치 사용 사례를 동일한 Delta 테이블과 결합합니다.
+ 데이터 모으기 중에 잘못된 레코드를 피하기 위한 자동 스키마 적용.
+ 데이터 버전 관리를 통한 시간 이동.
+ 변경 데이터 캡처(CDC), 스트리밍 업서트 등과 같은 복잡한 사용 사례에 대한 병합, 업데이트 및 삭제 작업을 지원합니다.

# Delta Lake가 설치된 클러스터 사용
<a name="Deltausing-cluster"></a>

**Topics**
+ [Flink와 함께 Delta Lake 클러스터 사용](Deltacluster-flink.md)
+ [Trino와 함께 Delta Lake 클러스터 사용](Deltacluster-trino.md)
+ [Spark와 함께 Delta Lake 클러스터 사용](Deltausing-cluster-spark.md)
+ [Spark 및 AWS Glue에서 Delta Lake 클러스터 사용](Deltacluster-spark-glue.md)

# Flink와 함께 Delta Lake 클러스터 사용
<a name="Deltacluster-flink"></a>

Amazon EMR 릴리스 6.11 이상에서는 Flink 클러스터에서 Delta Lake를 사용할 수 있습니다. 다음 예제에서는 AWS CLI 를 사용하여 Amazon EMR Flink 클러스터에서 Delta Lake로 작업합니다.

**참고**  
Amazon EMR은 Flink 클러스터에서 Delta Lake를 사용할 때 Flink DataStream API를 지원합니다.

## Delta Lake 클러스터 생성
<a name="Deltacreate-a-delta-cluster"></a>

1. 다음 콘텐츠가 포함된 `delta_configurations.json` 파일을 생성합니다.

   ```
   [{"Classification":"delta-defaults",  
       "Properties":{"delta.enabled":"true"}}]
   ```

1. 다음 구성을 사용하여 클러스터를 생성합니다. `example Amazon S3 bucket path` 및 `subnet ID`를 사용자 정보로 바꿉니다.

   ```
   aws emr create-cluster 
   --release-label emr-6.11.0   
   --applications Name=Flink  
   --configurations file://delta_configurations.json   
   --region us-east-1  --name My_Spark_Delta_Cluster  
   --log-uri  s3://amzn-s3-demo-bucket/  
   --instance-type m5.xlarge  
   --instance-count 3   
   --service-role EMR_DefaultRole_V2  
   --ec2-attributes  InstanceProfile=EMR_EC2_DefaultRole,SubnetId=subnet-1234567890abcdef0
   ```

## Flink yarn 세션 초기화
<a name="Deltainit-flink-yarn"></a>

Flink yarn 세션을 초기화하려면 다음 명령을 실행합니다.

```
flink-yarn-session -d
```

## Delta Lake를 사용하여 Flink 작업 빌드
<a name="Deltabuild-flink-with-delta-lake"></a>

다음 예제에서는 Delta Lake에서 sbt 또는 Maven을 사용해 Flink 작업을 빌드하는 방법을 보여줍니다.

------
#### [ sbt ]

[sbt](https://www.scala-sbt.org/1.x/docs/index.html)는 소규모 프로젝트의 경우 거의 또는 전혀 구성하지 않고도 사용할 수 있는 Scala용 빌드 도구입니다.

```
libraryDependencies ++= Seq(
  "io.delta" %% "delta-flink" % deltaConnectorsVersion % "provided",
  "io.delta" %% "delta-standalone" % deltaConnectorsVersion % "provided",
  "org.apache.flink" %% "flink-clients" % flinkVersion % "provided",
  "org.apache.flink" %% "flink-parquet" % flinkVersion % "provided",
  "org.apache.hadoop" % "hadoop-client" % hadoopVersion % "provided",
  "org.apache.flink" % "flink-table-common" % flinkVersion % "provided",
  "org.apache.flink" %% "flink-table-runtime" % flinkVersion % "provided")
```

------
#### [ Maven ]

[Maven](https://maven.apache.org)은 Apache Software Foundation의 오픈 소스 빌드 자동화 도구입니다. Maven을 사용하면 Amazon EMR에서 Delta Lake를 사용하여 Flink 작업을 빌드, 게시 및 배포할 수 있습니다.

```
<project>
<properties>
    <scala.main.version>2.12</scala.main.version>
    <delta-connectors-version>0.6.0</delta-connectors-version>
    <flink-version>1.16.1</flink-version>
    <hadoop-version>3.1.0</hadoop-version>
</properties>

<dependencies>
    <dependency>
        <groupId>io.delta</groupId>
        <artifactId>delta-flink</artifactId>
        <version>$delta-connectors-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.delta</groupId>
        <artifactId>delta-standalone_$scala-main-version</artifactId>
        <version>$delta-connectors-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients</artifactId>
        <version>$flink-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-parquet</artifactId>
        <version>$flink-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>$hadoop-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-common</artifactId>
        <version>$flink-version</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-runtime</artifactId>
        <version>$flink-version</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

------

## Flink Datastream API를 사용하여 Delta 테이블에 쓰기
<a name="Deltawrite-delta-table-with-flink-datastream-api"></a>

다음 예제를 사용하여 `deltaTablePath:`를 통해 테이블에 쓰도록 DeltaSink 생성

```
public static DataStream<RowData> createDeltaSink(
        DataStream<RowData> stream,
        String deltaTablePath,
        RowType rowType) {
    Configuration configuration = new Configuration();
    DeltaSink<RowData> deltaSink = DeltaSink
            .forRowData(
                    new org.apache.flink.core.fs.Path(deltaTablePath),
                    configuration,
                    rowType)
            .build();
    stream.sinkTo(deltaSink);
    return stream;
}
```

## Flink Datastream API를 사용하여 Delta 테이블에서 읽기
<a name="Deltaread-delta-table-with-flink-datastream-api"></a>

다음 예제를 사용하여 `deltaTablePath:`를 통해 테이블에서 데이터를 읽도록 바인딩된 DeltaSource 생성

```
public static DataStream<RowData> createBoundedDeltaSourceAllColumns(
        StreamExecutionEnvironment env,
        String deltaTablePath) {
    Configuration configuration = new Configuration();
    DeltaSource<RowData> deltaSource = DeltaSource
            .forBoundedRowData(
                    new org.apache.flink.core.fs.Path(deltaTablePath),
                    configuration)
            .build();

    return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
```

## Delta Lake 독립 실행형에 대한 다중 클러스터 지원을 통해 싱크 생성
<a name="Deltasink-creation-with-multi-cluster"></a>

다음 예제를 사용하여 `deltaTablePath` 및 [다중 클러스터 지원](https://docs.delta.io/latest/delta-standalone.html#multi-cluster-setup)을 통해 테이블에 쓰도록 DeltaSink를 생성합니다.

```
public DataStream<RowData> createDeltaSink(
        DataStream<RowData> stream,
        String deltaTablePath) {
    Configuration configuration = new Configuration();
    configuration.set("spark.delta.logStore.s3.impl", "io.delta.storage.S3DynamoDBLogStore");
    configuration.set("spark.io.delta.storage.S3DynamoDBLogStore.ddb.tableName", "delta_log");
    configuration.set("spark.io.delta.storage.S3DynamoDBLogStore.ddb.region", "us-east-1");
        
    DeltaSink<RowData> deltaSink = DeltaSink
        .forRowData(
            new Path(deltaTablePath),
            configuration,
            rowType)
        .build();
    stream.sinkTo(deltaSink);
    return stream;
}
```

## Flink 작업 실행
<a name="Deltarun-flink-job"></a>

다음 명령을 사용하여 작업을 실행합니다.

```
flink run FlinkJob.jar
```

# Trino와 함께 Delta Lake 클러스터 사용
<a name="Deltacluster-trino"></a>

Amazon EMR 릴리스 6.9.0 이상에서는 Trino 클러스터와 함께 Delta Lake를 사용할 수 있습니다.

이 자습서에서는를 사용하여 Amazon EMR Trino 클러스터에서 Delta Lake로 작업 AWS CLI 합니다.

## 
<a name="Deltacluster-trino-create"></a>

**Delta Lake 클러스터 생성**

1. `delta_configurations.json` 파일을 생성하고 선택한 카탈로그의 값을 설정합니다. 예를 들어, Hive 메타스토어를 카탈로그로 사용하려면 파일에 다음과 같은 콘텐츠가 있어야 합니다.

   ```
   [{"Classification":"delta-defaults",  
       "Properties":{"delta.enabled":"true"}},  
       {"Classification":"trino-connector-delta",  
       "Properties":{"hive.metastore.uri":"thrift://localhost:9083"}}]
   ```

    AWS Glue 카탈로그를 스토어로 사용하려면 파일에 다음 콘텐츠가 있어야 합니다.

   ```
   [{"Classification":"delta-defaults",  
       "Properties":{"delta.enabled":"true"}},  
       {"Classification":"trino-connector-delta",  
       "Properties":{"hive.metastore":"glue"}}]
   ```

1. 다음과 같은 구성으로 클러스터를 생성하고 **example Amazon S3 bucket path** 및 **subnet ID**를 사용자 정보로 바꿉니다.

   ```
   aws emr create-cluster 
       --release-label emr-6.9.0   
       --applications Name=Trino  
       --configurations file://delta_configurations.json   
       --region us-east-1  --name My_Spark_Delta_Cluster  
       --log-uri  s3://amzn-s3-demo-bucket/  
       --instance-type m5.xlarge  
       --instance-count 2   
       --service-role EMR_DefaultRole_V2  
       --ec2-attributes  InstanceProfile=EMR_EC2_DefaultRole,SubnetId=subnet-1234567890abcdef0
   ```

## Delta Lake용 Trino 세션 초기화
<a name="Deltainitialize-trino"></a>

Trino 세션을 초기화하려면 다음 명령을 실행합니다.

```
trino-cli --catalog delta
```

## Delta Lake 테이블에 쓰기
<a name="Deltatrino-write-table"></a>

다음 SQL 명령을 사용하여 테이블을 생성하고 테이블에 씁니다.

```
SHOW SCHEMAS;

CREATE TABLE default.delta_table (id  int, data varchar, category varchar) WITH 
( location =  's3://amzn-s3-demo-bucket/<prefix>');

INSERT INTO default.delta_table VALUES  (1,'a','c1'), (2,'b','c2'), (3,'c','c3');
```

## Delta Lake 테이블에서 읽기
<a name="Deltatrino-read-table"></a>

다음 SQL 명령을 사용하여 테이블에서 읽습니다.

```
SELECT * from default.delta_table;
```

# Spark와 함께 Delta Lake 클러스터 사용
<a name="Deltausing-cluster-spark"></a>

Amazon EMR 버전 6.9.0부터 부트스트랩 작업을 포함할 필요 없이 Spark 클러스터에서 Delta Lake를 사용할 수 있습니다. Amazon EMR 버전 6.8.0 이하의 경우 부트스트랩 작업을 사용하여 필요한 모든 종속 항목을 사전 설치할 수 있습니다.

다음 예제에서는 AWS CLI 를 사용하여 Amazon EMR Spark 클러스터에서 Delta Lake로 작업합니다.

에서 Amazon EMR의 Delta Lake를 사용하려면 AWS Command Line Interface먼저 클러스터를 생성합니다. Delta Lake 분류를 지정하는 방법에 대한 자세한 내용은 [클러스터를 생성할 AWS Command Line Interface 때를 사용하여 구성 제공](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-cli) 또는 클러스터를 생성할 때 Java SDK로 구성 제공을 AWS Command Line Interface참조하세요. [https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-sdk](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-sdk) 

1. 다음 콘텐츠가 포함된 `configurations.json` 파일을 생성합니다.

   ```
   [{"Classification":"delta-defaults",  "Properties":{"delta.enabled":"true"} }]
   ```

1. 다음과 같은 구성으로 클러스터를 생성하고 Amazon S3 **bucket path** 및 **subnet ID** 예제를 사용자 정보로 바꿉니다.

   ```
   aws emr create-cluster 
        --release-label  emr-6.9.0  
        --applications Name=Spark  
        --configurations file://delta_configurations.json   
        --region us-east-1  
        --name My_Spark_Delta_Cluster  
        --log-uri  s3://amzn-s3-demo-bucket/  
        --instance-type m5.xlarge  
        --instance-count 2   
        --service-role EMR_DefaultRole_V2  
        --ec2-attributes  InstanceProfile=EMR_EC2_DefaultRole,SubnetId=subnet-1234567890abcdef0
   ```

   또는 Spark 작업에서 다음 파일을 JAR 종속 항목으로 사용하여 Amazon EMR 클러스터와 Spark 애플리케이션을 생성할 수 있습니다.

   ```
   /usr/share/aws/delta/lib/delta-core.jar,
   /usr/share/aws/delta/lib/delta-storage.jar,    
   /usr/share/aws/delta/lib/delta-storage-s3-dynamodb.jar
   ```
**참고**  
Amazon EMR 릴리스 7.0.0 이상을 사용하는 경우 `/usr/share/aws/delta/lib/delta-spark.jar` 대신를 사용합니다`/usr/share/aws/delta/lib/delta-core.jar`.

   자세한 내용은 [애플리케이션 제출](https://spark.apache.org/docs/latest/submitting-applications.html#submitting-applications)을 참조하세요.

   jar를 Spark 작업에 jar 종속 항목으로 포함하려면 Spark 애플리케이션에 다음 구성 속성을 추가할 수 있습니다.

   ```
   --conf “spark.jars=/usr/share/aws/delta/lib/delta-core.jar,
        /usr/share/aws/delta/lib/delta-storage.jar,
        /usr/share/aws/delta/lib/delta-storage-s3-dynamodb.jar"
   ```

   Spark 작업 종속 항목에 대한 자세한 내용은 [Dependency Management](https://spark.apache.org/docs/latest/running-on-kubernetes.html#dependency-management)를 참조하세요.

   Amazon EMR 릴리스 7.0.0 이상을 사용하는 경우 대신 `/usr/share/aws/delta/lib/delta-spark.jar` 구성을 추가합니다.

   ```
   --conf “spark.jars=/usr/share/aws/delta/lib/delta-spark.jar,
        /usr/share/aws/delta/lib/delta-storage.jar,
        /usr/share/aws/delta/lib/delta-storage-s3-dynamodb.jar"
   ```

## Delta Lake용 Spark 세션 초기화
<a name="Deltainitialize-spark-session"></a>

다음 예제에서는 대화식 Spark 쉘을 시작하거나 Spark 제출을 사용하거나 Amazon EMR에서 Delta Lake를 작업하기 위해 Amazon EMR Notebooks를 사용하는 방법을 보여줍니다.

------
#### [ spark-shell ]

1. SSH를 사용하여 프라이머리 노드에 연결합니다. 자세한 내용은 *Amazon EMR 관리 안내서*에서 [SSH를 사용하여 프라이머리 노드에 연결](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)을 참조하세요.

1. Spark 셸을 시작하려면 다음 명령을 입력합니다. PySpark 쉘을 사용하려면 `spark-shell`을 `pyspark`로 바꿉니다.

   ```
   spark-shell \
      --conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" \
      --conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"
   ```

   Amazon EMR 릴리스 6.15.0 이상을 실행하는 경우 다음 구성을 사용하여 Delta Lake에서 Lake Formation을 기반으로 세분화된 액세스 제어를 사용해야 합니다.

   ```
   spark-shell \  
     --conf spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension \  
     --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog \  
     --conf spark.sql.catalog.spark_catalog.lf.managed=true
   ```

------
#### [ spark-submit ]

1. SSH를 사용하여 프라이머리 노드에 연결합니다. 자세한 내용은 *Amazon EMR 관리 안내서*에서 [SSH를 사용하여 프라이머리 노드에 연결](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)을 참조하세요.

1. Delta Lake용 Spark 세션을 시작하려면 다음 명령을 입력합니다.

   ```
   spark-submit  
   —conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" 
   —conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"
   ```

   Amazon EMR 릴리스 6.15.0 이상을 실행하는 경우 다음 구성을 사용하여 Delta Lake에서 Lake Formation을 기반으로 세분화된 액세스 제어를 사용해야 합니다.

   ```
   spark-submit \  `
   --conf spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension 
   --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog \  
   --conf spark.sql.catalog.spark_catalog.lf.managed=true
   ```

------
#### [ EMR Studio notebooks ]

Amazon EMR Studio 노트북을 사용하여 Spark 세션을 초기화하려면 다음 예제와 같이 Amazon EMR Notebooks에서 **%%configure** 매직 명령을 사용하여 Spark 세션을 구성합니다. 자세한 내용은 *Amazon EMR 관리 안내서*에서 [EMR Notebooks 매직 사용](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio-magics.html#emr-magics)을 참조하세요.

```
%%configure -f
{
  "conf": {
    "spark.sql.extensions":  "io.delta.sql.DeltaSparkSessionExtension",
     "spark.sql.catalog.spark_catalog":  "org.apache.spark.sql.delta.catalog.DeltaCatalog"
  }
}
```

Amazon EMR 릴리스 6.15.0 이상을 실행하는 경우 다음 구성을 사용하여 Delta Lake에서 Lake Formation을 기반으로 세분화된 액세스 제어를 사용해야 합니다.

```
%%configure -f   
{
  "conf": {
    "spark.sql.extensions": "io.delta.sql.DeltaSparkSessionExtension,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension",
    "spark.sql.catalog.spark_catalog": "org.apache.spark.sql.delta.catalog.DeltaCatalog",
    "spark.sql.catalog.spark_catalog.lf.managed": "true"
  }
}
```

------

## Delta Lake 테이블에 쓰기
<a name="Deltawrite-to-table"></a>

다음 예제에서는 Spark DataFrame을 생성하고 Delta Lake 데이터 세트로 쓰는 방법을 보여줍니다. 이 예제에서는 SSH를 기본 Hadoop 사용자로 사용하여 프라이머리 노드에 연결된 상태에서 Spark 쉘로 데이터 세트를 처리하는 방법을 보여줍니다.

**참고**  
코드 샘플을 Spark 쉘에 붙여넣으려면 프롬프트에 :paste를 입력하고 예제를 붙여넣은 다음 CTRL \$1 D를 누릅니다.

------
#### [ PySpark ]

Spark에는 Python 기반 쉘인 `pyspark`도 포함되어 있으며, 이 쉘을 사용하여 Python에서 작성된 Spark 프로그램을 시제품화할 수 있습니다. `spark-shell`과 마찬가지로 프라이머리 노드에서 `pyspark`를 간접 호출합니다.

```
## Create a DataFrame
data =  spark.createDataFrame([("100", "2015-01-01", "2015-01-01T13:51:39.340396Z"),
("101",  "2015-01-01", "2015-01-01T12:14:58.597216Z"),
("102", "2015-01-01", "2015-01-01T13:51:40.417052Z"),
("103",  "2015-01-01",  "2015-01-01T13:51:40.519832Z")],
["id", "creation_date",  "last_update_time"])

## Write a DataFrame as a Delta Lake dataset to the S3  location
spark.sql("""CREATE  TABLE IF NOT EXISTS delta_table (id string, creation_date string, 
last_update_time string)
USING delta location
's3://amzn-s3-demo-bucket/example-prefix/db/delta_table'""");

data.writeTo("delta_table").append()
```

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

```
import org.apache.spark.sql.SaveMode
import org.apache.spark.sql.functions._
 
// Create a DataFrame
val data = Seq(("100",  "2015-01-01",  "2015-01-01T13:51:39.340396Z"),
("101",  "2015-01-01",  "2015-01-01T12:14:58.597216Z"),
("102",  "2015-01-01", "2015-01-01T13:51:40.417052Z"),
("103",  "2015-01-01",  "2015-01-01T13:51:40.519832Z")).toDF("id", "creation_date",  "last_update_time")

// Write a DataFrame as a Delta Lake dataset to the S3  location
spark.sql("""CREATE  TABLE IF NOT EXISTS delta_table (id string,
creation_date string,
last_update_time string)
USING delta location
's3://amzn-s3-demo-bucket/example-prefix/db/delta_table'""");

data.write.format("delta").mode("append").saveAsTable("delta_table")
```

------
#### [ SQL ]

```
-- Create a Delta  Lake table with the S3 location
CREATE TABLE delta_table(id string,
creation_date string, 
last_update_time string)
USING delta LOCATION
's3://amzn-s3-demo-bucket/example-prefix/db/delta_table';

-- insert data into the table
INSERT INTO delta_table VALUES  ("100", "2015-01-01",  "2015-01-01T13:51:39.340396Z"),
("101",  "2015-01-01",  "2015-01-01T12:14:58.597216Z"),
("102",  "2015-01-01", "2015-01-01T13:51:40.417052Z"),
("103",  "2015-01-01", "2015-01-01T13:51:40.519832Z");
```

------

## Delta Lake 테이블에서 읽기
<a name="Deltaread-from-table"></a>

------
#### [ PySpark ]

```
ddf = spark.table("delta_table")
ddf.show()
```

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

```
val ddf =  spark.table("delta_table")
ddf.show()
```

------
#### [ SQL ]

```
SELECT * FROM delta_table;
```

------

# Spark 및 AWS Glue에서 Delta Lake 클러스터 사용
<a name="Deltacluster-spark-glue"></a>

 AWS Glue 카탈로그를 Delta Lake 테이블의 메타스토어로 사용하려면 다음 단계를 수행하여 클러스터를 생성합니다. 를 사용하여 Delta Lake 분류를 지정하는 방법에 대한 자세한 내용은 [ 클러스터를 생성할 AWS Command Line Interface 때를 사용하여 구성 제공](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-cli) 또는 클러스터를 생성할 때 Java SDK를 사용하여 구성 제공을 AWS Command Line Interface참조하세요. [https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-sdk](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-create-cluster.html#emr-configure-apps-create-cluster-sdk) 

**Delta Lake 클러스터 생성**

1. 다음 콘텐츠가 포함된 `configurations.json` 파일을 생성합니다.

   ```
   [{"Classification":"delta-defaults",  
   "Properties":{"delta.enabled":"true"}},
   {"Classification":"spark-hive-site",
   "Properties":{"hive.metastore.client.factory.class":"com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"}}]
   ```

1. 다음과 같은 구성으로 클러스터를 생성하고 **example Amazon S3 bucket path** 및 **subnet ID**를 사용자 정보로 바꿉니다.

   ```
   aws emr create-cluster 
       --release-label  emr-6.9.0  
       --applications Name=Spark  
       --configurations file://delta_configurations.json 
       --region us-east-1  
       --name My_Spark_Delta_Cluster  
       --log-uri  s3://amzn-s3-demo-bucket/  
       --instance-type m5.xlarge  
       --instance-count 2   
       --service-role EMR_DefaultRole_V2  
       --ec2-attributes  InstanceProfile=EMR_EC2_DefaultRole,SubnetId=subnet-1234567890abcdef0
   ```

# 고려 사항 및 제한 사항
<a name="Deltaconsiderations-limitations"></a>
+ Delta Lake는 Amazon EMR 릴리스 6.9.0 이상에서 함께 사용할 수 있습니다. Delta 테이블이 있는 Amazon EMR 클러스터에서 [Apache Spark](https://aws.amazon.com/emr/features/spark/) 3.x를 사용할 수 있습니다.
+ 최상의 성능, 보안 및 안정성을 위해 s3a 대신 S3 위치 경로에 s3 URI 스키마를 사용하는 것이 좋습니다. 자세한 내용은 [스토리지 및 파일 시스템 작업](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-file-systems.html)을 참조하세요.
+ Amazon EMR 7.0에서는 Delta Universal Format (UniForm) 및 convert-to-Iceberg 명령문이 지원되지 않습니다.
+ Amazon EMR 6.9 및 6.10에서 Amazon S3에 Delta Lake 테이블 데이터를 저장하면 열 이름 바꾸기 작업 후에 열 데이터가 `NULL`이 됩니다. 이 문제는 Amazon EMR 6.11에서 해결되었습니다. 이 실험적인 열 이름 바꾸기 작업에 대한 자세한 내용은 Delta Lake 사용 설명서에서 [Column rename operation](https://docs.delta.io/latest/delta-batch.html#rename-columns)을 참조하세요.
+ 베이징(cn-north-1) 리전에서 Glue와 함께 EMR Delta를 사용하는 경우 `hive.s3.endpoint`를 `https://s3---cn-north-1.amazonaws.com.rproxy.govskope.us.cn`으로 설정합니다.
+ Apache Spark 외부의 AWS Glue 데이터 카탈로그에서 데이터베이스를 생성하는 경우 데이터베이스에 빈 `LOCATION` 필드가 있을 수 있습니다. Spark에서는 빈 위치 속성으로 데이터베이스를 생성할 수 없으므로 Amazon EMR에서 Spark를 사용하여 Glue 데이터베이스에 Delta 테이블을 생성하고 데이터베이스에 빈 속성이 있는 경우 `LOCATION` 오류가 발생합니다.

  ```
  IllegalArgumentException: Can not create a Path from an empty string
  ```

  이 문제를 해결하려면 `LOCATION` 필드에 대한 비어 있지 않은 유효한 경로를 사용하여 데이터 카탈로그에서 데이터베이스를 생성합니다. 이 솔루션을 구현하는 단계는 *Amazon Athena 사용 설명서*에서 [테이블을 생성할 때 잘못된 인수 예외 발생](https://docs.aws.amazon.com/athena/latest/ug/notebooks-spark-known-issues.html#notebooks-spark-known-issues-illegal-argument-exception)을 참조하세요.

# Delta 릴리스 기록
<a name="Delta-release-history"></a>

다음 테이블에는 애플리케이션과 함께 설치된 구성 요소 외에도 Amazon EMR의 최신 릴리스에 포함된 Delta의 버전이 나열되어 있습니다. 각 릴리스의 구성 요소 버전은 [Amazon EMR 7.x 릴리스 버전](emr-release-7x.md), [Amazon EMR 6.x 릴리스 버전](emr-release-6x.md) 또는 [Amazon EMR 5.x 릴리스 버전](emr-release-5x.md)의 릴리스의 구성 요소 버전 섹션을 참조하세요.


**Delta 버전 정보**  

| Amazon EMR 릴리스 레이블 | Delta 버전 | Delta와 함께 설치된 구성 요소 | 
| --- | --- | --- | 
| emr-7.12.0 | 3.3.2-amzn-1 | Not available. | 
| emr-7.11.0 | 3.3.2-amzn-0 | Not available. | 
| emr-7.10.0 | 3.3.0-amzn-2 | Not available. | 
| emr-7.9.0 | 3.3.0-amzn-1 | Not available. | 
| emr-7.8.0 | 3.3.0-amzn-0 | Not available. | 
| emr-7.7.0 | 3.2.1-amzn-2 | Not available. | 
| emr-7.6.0 | 3.2.1-amzn-1 | Not available. | 
| emr-7.5.0 | 3.2.1-amzn-0 | Not available. | 
| emr-7.4.0 | 3.2.0-amzn-1 | Not available. | 
| emr-7.3.0 | 3.2.0-amzn-0 | Not available. | 
| emr-7.2.0 | 3.1.0 | Not available. | 
| emr-7.1.0 | 3.0.0 | Not available. | 
| emr-7.0.0 | 3.0.0 | Not available. | 
| emr-6.15.0 | 2.4.0 | Not available. | 
| emr-6.14.0 | 2.4.0 | Not available. | 
| emr-6.13.0 | 2.4.0 | Not available. | 
| emr-6.12.0 | 2.4.0 | Not available. | 
| emr-6.11.1 | 2.2.0 | Not available. | 
| emr-6.11.0 | 2.2.0 | Not available. | 
| emr-6.10.1 | 2.2.0 | Not available. | 
| emr-6.10.0 | 2.2.0 | Not available. | 
| emr-6.9.1 | 2.1.0 | Not available. | 
| emr-6.9.0 | 2.1.0 | Not available. | 