

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

# Amazon EMR을 사용하여 DynamoDB에서 테이블 내보내기, 가져오기, 쿼리 및 조인
<a name="EMRforDynamoDB"></a>

**참고**  
Amazon EMR-DynamoDB 커넥터는 GitHub에서 오픈 소스로 제공됩니다. 자세한 내용은 [https://github.com/awslabs/emr-dynamodb-connector](https://github.com/awslabs/emr-dynamodb-connector)를 참조하세요.

DynamoDB는 완전관리형 NoSQL 데이터베이스 서비스로, 원활한 확장성과 함께 빠르고 예측 가능한 성능을 제공합니다. 개발자는 데이터베이스 테이블을 만들고 해당 요청 트래픽 또는 스토리지를 제한 없이 확장할 수 있습니다. DynamoDB는 테이블의 데이터와 트래픽을 충분한 수의 서버로 자동 분산하여 고객이 지정한 요청 용량과 저장된 데이터 규모를 처리하면서도 일관되고 빠른 성능을 발휘합니다. 여기에 Amazon EMR 및 Hive를 사용하면 DynamoDB에 저장된 데이터와 같은 대용량 데이터도 빠르고 효율적으로 처리할 수 있습니다. DynamoDB에 대한 자세한 내용은 [Amazon DynamoDB 개발자 안내서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/)를 참조하세요.

Apache Hive는 사용이 쉬우면서 SQL과 유사한 쿼리 언어(HiveQL)로 map reduce 클러스터에 대해 쿼리를 실행할 때 사용하는 소프트웨어 계층입니다. 이 소프트웨어는 Hadoop 아키텍처를 기반으로 실행됩니다. Hive 및 HiveQL에 대한 자세한 내용은 [HiveQL language manual](https://cwiki.apache.org/confluence/display/Hive/LanguageManual)을 참조하세요. Hive 및 Amazon EMR에 대한 자세한 내용은 [Apache Hive](emr-hive.md) 섹션을 참조하세요.

DynamoDB 연결 기능이 포함된 사용자 지정 버전의 Hive와 함께 Amazon EMR 사용하여 DynamoDB에 저장된 데이터에 대해 다음 작업을 수행할 수 있습니다.
+ DynamoDB 데이터를 Hadoop 분산 파일 시스템(HDFS)에 로드한 후 Amazon EMR 클러스터에 대한 입력으로 사용.
+ 유사 SQL 문(HiveQL)을 사용하여 실시간 DynamoDB 데이터 쿼리.
+ DynamoDB에 저장된 데이터 조인 및 내보내기 또는 조인된 데이터 쿼리.
+ DynamoDB에 저장된 데이터를 Amazon S3로 내보내기.
+ Amazon S3에서 DynamoDB로 데이터 가져오기.

**참고**  
Amazon EMR-DynamoDB 커넥터는 [Kerberos 인증](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-kerberos.html)을 사용하도록 구성된 클러스터를 지원하지 않습니다.

다음 각 작업을 수행하려면 먼저 Amazon EMR 클러스터를 시작하고 DynamoDB에서 데이터 위치를 지정한 다음, Hive 명령을 실행하여 DynamoDB에 저장된 데이터를 조작합니다.

Amazon EMR 클러스터를 시작하는 방법에는 여러 가지가 있습니다. Amazon EMR 콘솔, 명령줄 인터페이스(CLI)를 사용하거나 AWS SDK 또는 Amazon EMR API를 사용하여 클러스터를 프로그래밍할 수 있습니다. 그 밖에 Hive 클러스터를 대화식으로 실행할지, 아니면 스크립트에서 실행할지 선택할 수도 있습니다. 이 섹션에서는 Amazon EMR 콘솔과 CLI를 사용하여 대화형 Hive 클러스터를 시작하는 방법에 대해 살펴보겠습니다.

대화식 Hive 사용은 쿼리 성능을 테스트하고 애플리케이션을 조정하는 데 효과적인 방법입니다. 정기적으로 실행할 Hive 명령 세트를 설정한 후 Amazon EMR에서 자동으로 실행할 수 있는 Hive 스크립트를 생성할 수 있습니다.

**주의**  
DynamoDB 테이블에서 Amazon EMR 읽기 또는 쓰기 작업은 구성된 프로비저닝된 처리량을 소모하여 프로비저닝된 처리량 예외의 발생 주기가 늘어날 가능성이 큽니다. 그래서 Amazon EMR은 대용량 요청을 대비해 지수 백오프 알고리즘을 통한 재시도를 구현함으로써 DynamoDB 테이블에 대한 요청 로드를 관리합니다. Amazon EMR 작업을 다른 트래픽과 동시에 실행하면 할당된 프로비저닝된 처리량 수준을 초과할 수 있습니다. Amazon CloudWatch의 **ThrottleRequests** 지표를 확인하여 이 상태를 모니터링할 수 있습니다. 요청 로드가 너무 높으면 클러스터를 다시 시작한 후 [읽기 비율 설정](EMR_Hive_Optimizing.md#ReadPercent) 또는 [쓰기 비율 설정](EMR_Hive_Optimizing.md#WritePercent)을 더 낮은 값으로 설정하여 Amazon EMR 작업을 조절할 수 있습니다. DynamoDB 처리량 설정에 대한 자세한 내용은 [프로비저닝된 처리량](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithDDTables.html#ProvisionedThroughput)을 참조하세요.  
테이블이 [온디맨드 모드](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand)로 구성된 경우 내보내기 또는 가져오기 작업을 실행하기 전에 테이블을 프로비저닝된 모드로 다시 변경해야 합니다. DynamoDB 테이블에서 사용할 리소스를 계산하려면 파이프라인에 처리량 비율이 필요합니다. 온디맨드 모드는 프로비저닝된 처리량을 제거합니다. 처리량 용량을 프로비저닝하려는 경우 Amazon CloudWatch Events 지표를 사용하여 테이블에서 사용하는 총 처리량을 평가할 수 있습니다.

**Topics**
+ [Hive 테이블을 설정하여 Hive 명령 실행](EMR_Interactive_Hive.md)
+ [DynamoDB에서 데이터 내보내기, 가져오기 및 쿼리를 위한 Hive 명령 예제](EMR_Hive_Commands.md)
+ [DynamoDB에서 Amazon EMR 작업 성능 최적화](EMR_Hive_Optimizing.md)

# Hive 테이블을 설정하여 Hive 명령 실행
<a name="EMR_Interactive_Hive"></a>

데이터 웨어하우스 애플리케이션인 Apache Hive는 유사 SQL 언어를 사용하여 Amazon EMR 클러스터에 포함된 데이터를 쿼리하는 데 사용할 수 있습니다. Hive에 대한 자세한 내용은 [http://hive.apache.org/](http://hive.apache.org/)를 참조하세요.

다음 절차에서는 이미 클러스터를 생성하고 Amazon EC2 키 페어를 지정했다고 가정합니다. 클러스터 생성을 시작하는 방법에 대한 자세한 내용은* Amazon EMR 관리 안내서*에서 [Amazon EMR 시작하기](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-gs)를 참조하세요.

## MapReduce를 사용하도록 Hive 구성
<a name="hive-mapreduce"></a>

DynamoDB 테이블을 쿼리하기 위해 Amazon EMR에서 Hive를 사용하는 경우 Hive에 기본 실행 엔진인 Tez가 사용된다면 오류가 발생할 수 있습니다. 이런 이유로 이 섹션에서 설명한 대로 DynamoDB와 통합되는 Hive를 사용해 클러스터를 생성하는 경우 MapReduce를 사용하도록 Hive를 설정하는 구성 분류를 사용하는 것이 좋습니다. 자세한 내용은 [애플리케이션 구성](emr-configure-apps.md) 단원을 참조하십시오.

다음 조각은 MapReduce를 Hive용 실행 엔진으로 설정하기 위해 사용하는 구성 분류 및 속성을 보여줍니다.

```
[
                {
                    "Classification": "hive-site",
                    "Properties": {
                        "hive.execution.engine": "mr"
                    }
                }
             ]
```<a name="EMR_Interactive_Hive_session"></a>

**Hive 명령을 대화식으로 실행하려면**

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

1. 현재 마스터 노드에 대한 명령 프롬프트에 `hive`를 입력합니다.

   Hive 프롬프트 `hive>`가 표시됩니다.

1.  Hive 애플리케이션의 테이블을 DynamoDB의 데이터에 매핑하는 Hive 명령을 입력합니다. 이 테이블은 Amazon DynamoDB에 저장된 데이터에 대한 참조로 사용되며, 데이터는 Hive에 로컬로 저장되지 않습니다. 따라서 이 테이블을 사용하는 모든 쿼리는 DynamoDB의 실시간 데이터에 대해 실행되므로 명령을 실행할 때마다 테이블의 읽기 또는 쓰기 용량이 소비됩니다. 동일한 데이터 세트에 대해 여러 Hive 명령을 실행하려면 먼저 해당 데이터 세트를 내보내는 것을 고려해 보세요.

    다음은 Hive 테이블을 DynamoDB 테이블에 매핑하는 구문을 보여 줍니다.

   ```
   CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...)
   STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", 
   "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...");
   ```

    DynamoDB에서 Hive에 테이블을 생성하는 경우 `EXTERNAL` 키워드를 사용하여 외부 테이블로 생성해야 합니다. 외부 테이블과 내부 테이블의 차이점은 내부 테이블을 삭제하면 내부 테이블의 데이터가 삭제된다는 점입니다. 이는 Amazon DynamoDB에 연결된 경우에 바람직한 동작이 아니므로 외부 테이블만 지원됩니다.

    예를 들어, 다음 Hive 명령은 Hive에서 DynamoDB 테이블* dynamodbtable1*을 참조하는 *hivetable1* 테이블을 생성합니다. DynamoDB 테이블 *dynamodbtable1*에는 해시 및 범위 프라이머리 키 스키마가 있습니다. 해시 키 요소는 `name`(문자열 형식)이고, 범위 키 요소는 `year`(숫자 형식)이고, 각 항목에는 `holidays`(문자열 세트 형식)에 대한 속성 값이 있습니다.

   ```
   CREATE EXTERNAL TABLE hivetable1 (col1 string, col2 bigint, col3 array<string>)
   STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
   "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");
   ```

    라인 1에서는 HiveQL `CREATE EXTERNAL TABLE` 문을 사용합니다. *hivetable1*에 대해 DynamoDB 테이블의 각 속성 이름 및 값 페어에 대한 열을 설정하고 데이터 형식을 제공해야 합니다. 이러한 값은 대소문자를 구분하지 않으므로 열에 예약어를 제외한 모든 이름을 지정할 수 있습니다.

    라인 2에서는 `STORED BY` 문을 사용합니다. `STORED BY`의 값은 Hive와 DynamoDB 사이의 연결을 처리하는 클래스의 이름입니다. `'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'`로 설정되어야 합니다.

    행 3에서는 `TBLPROPERTIES` 문을 사용하여 'hivetable1'을 DynamoDB의 올바른 테이블 및 스키마에 연결합니다. `TBLPROPERTIES`에 `dynamodb.table.name` 및 `dynamodb.column.mapping` 파라미터의 값을 제공합니다. 이러한 값은 대소문자를 *구분합니다*.
**참고**  
 테이블에 대한 모든 DynamoDB 속성 이름은 Hive 테이블에 해당 열이 있어야 합니다. Amazon EMR 버전에 따라 다음 시나리오는 일대일 매핑이 존재하지 않는 경우 발생합니다.  
Amazon EMR 5.27.0 이상 버전의 경우, 커넥터에는 DynamoDB 속성 이름과 Hive 테이블에 있는 열 간의 일대일 매핑을 확인하는 검증이 포함되어 있습니다. 일대일 매핑이 존재하지 않으면 오류가 발생합니다.
Amazon EMR 5.26.0 이하 버전의 경우, Hive 테이블에는 DynamoDB의 이름 및 값 페어가 포함되지 않습니다. DynamoDB 프라이머리 키 속성을 매핑하지 않을 경우 Hive에서 오류가 발생합니다. 비기본 키 속성을 매핑하지 않는 경우에는 오류가 발생하지 않지만 Hive 테이블에 데이터가 표시되지 않습니다. 데이터 형식이 일치하지 않으면 값은 널입니다.

그런 다음 *hivetable1*에서 Hive 작업을 실행할 수 있습니다. *hivetable1*에 대해 실행되는 쿼리는 DynamoDB 계정의 DynamoDB 테이블 *dynamodbtable1*에 대해 내부적으로 실행되며, 실행할 때마다 읽기 또는 쓰기 유닛을 소비합니다.

DynamoDB 테이블에 대해 Hive 쿼리를 실행하는 경우 충분한 양의 읽기 용량 유닛을 프로비저닝했는지 확인해야 합니다.

예를 들어, DynamoDB 테이블에 읽기 용량 단위를 100개 프로비저닝하였다고 가정하겠습니다. 그러면 초당 100회의 읽기(또는 409,600바이트)를 수행할 수 있습니다. 테이블에 20GB의 데이터(21,474,836,480바이트)가 포함되어 있고 Hive 쿼리에서 전체 테이블 스캔을 수행하는 경우 쿼리를 실행하는 데 걸리는 시간을 추산할 수 있습니다.

 * 21,474,836,480 / 409,600 = 52,429초 = 14.56시간 * 

필요한 시간을 줄일 수 있는 유일한 방법은 원본 DynamoDB 테이블에서 읽기 용량 유닛을 조정하는 것입니다. Amazon EMR 노드를 더 추가하더라도 효과가 없습니다.

Hive 출력에서 하나 이상의 매퍼 프로세스가 완료되면 진행률이 업데이트됩니다. 하지만 대용량 DynamoDB 테이블에서 프로비저닝된 읽기 용량이 낮게 설정된 경우에는 진행률 출력이 오랫동안 업데이트되지 않을 수도 있습니다. 위 경우에는 작업 진행률이 몇 시간 0%로 표시됩니다. 작업 진행률에 대한 자세한 상태를 보려면 Amazon EMR 콘솔로 이동하여 개별 매퍼 작업 상태와 데이터 읽기에 대한 통계를 볼 수 있습니다. 마스터 노드에서 Hadoop 인터페이스에 로그온하여 Hadoop 통계를 볼 수도 있습니다. 여기에는 개별 맵 작업 상태와 일부 데이터 읽기 통계가 표시됩니다. 자세한 내용은 다음 항목을 참조하세요.
+ [프라이머리 노드에 호스팅된 웹 인터페이스](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-web-interfaces.html)
+ [Hadoop 웹 인터페이스 보기](https://docs.aws.amazon.com/emr/latest/ManagementGuide/UsingtheHadoopUserInterface.html)

DynamoDB에서 데이터 내보내기 또는 가져오기 및 테이블 조인과 같은 작업을 수행하는 샘플 HiveQL 문에 대한 자세한 내용은 [DynamoDB에서 데이터 내보내기, 가져오기 및 쿼리를 위한 Hive 명령 예제](EMR_Hive_Commands.md) 섹션을 참조하세요.<a name="EMR_Hive_Cancel"></a>

**Hive 요청을 취소하려면**

Hive 쿼리를 실행할 때 서버의 초기 응답에는 요청을 취소하는 명령이 포함되어 있습니다. 프로세스 중에 언제든지 요청을 취소하려면 서버 응답에서 **Kill Command(Kill 명령)**를 사용합니다.

1. 명령줄 클라이언트를 종료하려면 `Ctrl+C`를 입력합니다.

1.  셸 프롬프트에서 요청에 대한 초기 서버 응답의 **Kill Command(Kill 명령)**를 입력합니다.

    또는 마스터 노드의 명령줄에서 다음 명령을 실행하여 Hadoop 작업을 종료할 수 있습니다. 여기서 *job-id*는 Hadoop 작업의 식별자이며 Hadoop 사용자 인터페이스에서 검색할 수 있습니다.

   ```
   hadoop job -kill job-id
   ```

## Hive 및 DynamoDB에 대한 데이터 유형
<a name="EMR_Hive_Properties"></a>

다음 테이블에는 사용 가능한 Hive 데이터 유형, 해당하는 기본 DynamoDB 유형, 매핑할 수 있는 대체 DynamoDB 유형이 나와 있습니다.


| Hive 형식 | 기본 DynamoDB 유형 | 대체 DynamoDB 유형 | 
| --- | --- | --- | 
| 문자열 | 문자열(S) |  | 
| bigint 또는 double | 숫자(N) |  | 
| 이진수 | 이진수(B) |  | 
| 부울 | BOOLEAN (BOOL) |  | 
| 배열 | list (L) | 숫자 세트(NS), 문자열 세트(SS) 또는 이진수 세트(BS) | 
| map<string,string> | item | map (M) | 
| map<string,?> | map (M) |  | 
|  | null (NULL) |  | 

Hive 데이터를 해당하는 대체 DynamoDB 유형으로 쓰거나 DynamoDB 데이터에 대체 DynamoDB 유형의 대체값이 포함된 경우 `dynamodb.type.mapping` 파라미터를 이용해 열 및 DynamoDB 유형을 지정할 수 있습니다. 다음 예제는 대체 형식 매핑을 지정하기 위한 구문을 보여줍니다.

```
CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...)
STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename",
"dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...",
"dynamodb.type.mapping" = "hive_column1_name:dynamodb_attribute1_datatype");
```

형식 매핑 파라미터는 선택 사항이며 대체 형식을 사용하는 열에 대해서만 지정해야 합니다.

예를 들어, 다음 Hive 명령은 DynamoDB 테이블 `dynamodbtable2`를 참조하는 `hivetable2`라는 테이블을 생성합니다. `col3` 열을 문자열 집합(SS) 형식으로 매핑하는 것을 제외하고는 `hivetable1`와 유사합니다.

```
CREATE EXTERNAL TABLE hivetable2 (col1 string, col2 bigint, col3 array<string>)
STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable2",
"dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays",
"dynamodb.type.mapping" = "col3:SS");
```

Hive에서 `hivetable1` 및 `hivetable2`는 동일합니다. 하지만 이러한 테이블에 있는 데이터는 해당하는 DynamoDB 테이블에 기록되며, `dynamodbtable1`은 목록을 포함하고 `dynamodbtable2`는 문자열 세트를 포함합니다.

Hive `null` 값을 DynamoDB `null` 유형의 속성으로 작성하려는 경우 `dynamodb.null.serialization` 파라미터를 사용하면 됩니다. 다음 예제는 `null` 직렬화를 지정하기 위한 구문을 보여줍니다.

```
CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...)
STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename",
"dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...",
"dynamodb.null.serialization" = "true");
```

Null 직렬화 파라미터는 선택 사항이며 지정하지 않으면 `false`로 설정됩니다. DynamoDB `null` 속성은 파라미터 설정에 상관없이 Hive의 `null` 값으로 읽힙니다. `null` 값을 가진 Hive 컬렉션은 null 직렬화 파라미터가 `true`로 설정된 경우에만 DynamoDB에 기록됩니다. 그렇지 않으면 Hive 오류가 발생합니다.

Hive의 bigint 형식은 Java long 형식과 동일하고, Hive double 형식은 정밀도의 측면에서 Java double 형식과 동일합니다. 즉, Hive 데이터 유형에서 사용할 수 있는 것보다 더 높은 정밀도를 가진 숫자 데이터가 DynamoDB에 저장되어 있는 경우 Hive를 사용하여 DynamoDB 데이터를 내보내거나, 가져오거나, 참조하면 정밀도가 손실되거나 Hive 쿼리 오류가 발생할 수 있습니다.

 DynamoDB에서 Amazon Simple Storage Service(S3) 또는 HDFS로 내보낸 이진수 유형은 Base64로 인코딩된 문자열로 저장됩니다. 데이터를 Amazon S3 또는 HDFS에서 DynamoDB 이진수 유형으로 가져올 경우 데이터를 Base64 문자열로 인코딩해야 합니다.

## Hive 옵션
<a name="EMR_Hive_Options"></a>

 다음 Hive 옵션을 설정하여 Amazon DynamoDB에서의 데이터 전송을 관리할 수 있습니다. 이러한 옵션은 현재 Hive 세션 동안만 지속됩니다. Hive 명령 프롬프트를 닫았다가 나중에 클러스터에서 다시 열면 해당 설정은 기본값으로 되돌아갑니다.


| Hive 옵션 | 설명 | 
| --- | --- | 
| dynamodb.throughput.read.percent |   DynamoDB 프로비저닝 처리 속도를 테이블에 할당된 범위로 유지하도록 읽기 작업 속도를 설정합니다. 값은 `0.1`과 `1.5` 사이입니다.  값 0.5는 기본 읽기 속도이며, 이 설정에서 Hive는 테이블에서 읽기 프로비저닝된 처리량 리소스의 1/2을 소비하려고 시도합니다. 이 값을 0.5보다 크게 설정하면 읽기 요청 속도가 빨라집니다. 이 값을 0.5보다 작게 설정하면 읽기 요청 속도가 느려집니다. 이 읽기 속도는 근사값입니다. 실제 읽기 속도는 DynamoDB의 키 분포가 균일한지 여부와 같은 요소에 따라 달라집니다.  Hive 작업에서 프로비저닝된 처리량을 자주 초과하거나 실시간 읽기 트래픽 병목 현상이 너무 자주 발생하는 경우 이 값을 `0.5`보다 작게 줄이세요. 용량이 충분하고 Hive 작업을 더 빠르게 수행하려면 이 값을 `0.5`보다 크게 설정하세요. 사용되지 않은 입력/출력 작업이 사용 가능한 경우 이 값을 최대 1.5까지 초과 설정할 수도 있습니다.  | 
| dynamodb.throughput.write.percent |   DynamoDB 프로비저닝 처리 속도를 테이블에 할당된 범위로 유지하도록 쓰기 작업 속도를 설정합니다. 값은 `0.1`과 `1.5` 사이입니다.  값 0.5는 기본 쓰기 속도이며, 이 설정에서 Hive는 테이블에서 쓰기 프로비저닝된 처리량 리소스의 1/2을 소비하려고 시도합니다. 이 값을 0.5보다 크게 설정하면 쓰기 요청 속도가 빨라집니다. 이 값을 0.5보다 작게 설정하면 쓰기 요청 속도가 느려집니다. 이 쓰기 속도는 근사값입니다. 실제 쓰기 속도는 DynamoDB의 키 분포가 균일한지 여부와 같은 요소에 따라 달라집니다.  Hive 작업에서 프로비저닝된 처리량을 자주 초과하거나 실시간 쓰기 트래픽 병목 현상이 너무 자주 발생하는 경우 이 값을 `0.5`보다 작게 줄이세요. 용량이 충분하고 Hive 작업을 더 빠르게 수행하려면 이 값을 `0.5`보다 크게 설정하세요. 사용되지 않은 입력/출력 작업이 사용 가능한 경우나 테이블에 데이터를 처음으로 업로드하고 아직 실시간 트래픽이 없는 경우 이 값을 최대 1.5까지 초과 설정할 수도 있습니다.  | 
| dynamodb.endpoint | DynamoDB 서비스에 대한 엔드포인트를 지정합니다. 사용 가능한 DynamoDB 엔드포인트에 대한 자세한 내용은 [리전 및 엔드포인트](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)를 참조하세요.  | 
| dynamodb.max.map.tasks |   DynamoDB에서 데이터를 읽을 때 최대 맵 작업 수를 지정합니다. 이 값은 1보다 크거나 같아야 합니다.  | 
| dynamodb.retry.duration |   Hive 명령 재시도를 위한 제한 시간으로 사용할 시간(분)을 지정합니다. 이 값은 0보다 크거나 같은 정수입니다. 기본 제한 시간은 1분입니다.  | 

 다음 예제에 표시된 것처럼 이러한 값은 `SET` 명령을 사용하여 설정합니다.

```
SET dynamodb.throughput.read.percent=1.0; 

INSERT OVERWRITE TABLE s3_export SELECT * 
FROM hiveTableName;
```

# DynamoDB에서 데이터 내보내기, 가져오기 및 쿼리를 위한 Hive 명령 예제
<a name="EMR_Hive_Commands"></a>

다음 예제에서는 Hive 명령을 사용하여 Amazon S3 또는 HDFS로 데이터 내보내기, DynamoDB로 데이터 가져오기, 테이블 조인, 테이블 쿼리 등의 작업을 수행합니다.

Hive 테이블에서의 작업은 DynamoDB에 저장된 데이터를 참조합니다. Hive 명령에는 DynamoDB 테이블의 프로비저닝된 처리량 설정이 적용되며 가져오는 데이터에는 DynamoDB에서 Hive 작업 요청을 처리할 때 DynamoDB 테이블에 쓰여진 데이터가 포함됩니다. 데이터 검색 프로세스가 오래 걸리면 Hive 명령 시작 이후 Hive 명령이 반환하는 일부 데이터가 DynamoDB에서 업데이트된 것일 수 있습니다.

Hive 명령 `DROP TABLE` 및 `CREATE TABLE`은 Hive의 로컬 테이블에만 적용되며 DynamoDB에서 테이블을 생성하거나 삭제하지 않습니다. Hive 쿼리가 DynamoDB의 테이블을 참조할 경우 쿼리를 실행하기 전에 해당 테이블이 이미 있어야 합니다. DynamoDB에서 테이블을 생성하고 삭제하는 방법에 대한 자세한 내용은 *Amazon DynamoDB 개발자 안내서*에서 [DynamoDB의 테이블 작업](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html)을 참조하세요.

**참고**  
 Hive 테이블을 Amazon S3의 위치에 매핑하는 경우 버킷의 루트 경로인 s3://amzn-s3-demo-bucket에 매핑하지 않습니다. 이 경우 Hive에서 Amazon S3에 데이터를 쓸 때 오류가 발생할 수 있습니다. 대신, 버킷의 하위 경로인 s3://amzn-s3-demo-bucket/mypath에 테이블을 매핑합니다.

## DynamoDB에서 데이터 내보내기
<a name="EMR_Hive_Commands_exporting"></a>

 Hive를 사용하여 DynamoDB에서 데이터를 내보낼 수 있습니다.

**Amazon S3 버킷으로 DynamoDB 테이블을 내보내는 방법**
+  DynamoDB에 저장된 데이터를 참조하는 Hive 테이블을 생성합니다. 그러면 INSERT OVERWRITE 명령을 호출하여 외부 디렉터리에 데이터를 쓸 수 있습니다. 다음 예제에서 *s3://amzn-s3-demo-bucket/path/subpath/*는 Amazon S3의 유효한 경로입니다. DynamoDB의 값에 맞게 CREATE 명령에서 열과 데이터 형식을 조정합니다. 이 항목을 사용하여 Amazon S3에서 DynamoDB 데이터의 아카이브를 생성할 수 있습니다.

  ```
  1. CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
  2. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
  3. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
  4. "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");                   
  5.                     
  6. INSERT OVERWRITE DIRECTORY 's3://amzn-s3-demo-bucket/path/subpath/' SELECT * 
  7. FROM hiveTableName;
  ```

**형식을 사용하여 DynamoDB 테이블을 Amazon S3 버킷으로 내보내는 방법**
+  Amazon S3 내 위치를 참조하는 외부 테이블을 생성합니다. 이 작업은 s3\$1export로 아래에 표시됩니다. CREATE 호출 중에 테이블의 행 형식을 지정합니다. 그러면 INSERT OVERWRITE를 사용하여 DynamoDB에서 s3\$1export로 데이터를 내보낼 때 지정된 형식으로 데이터가 쓰여집니다. 다음 예제에서는 쉼표로 구분된 값(CSV)으로 데이터가 쓰여집니다.

  ```
   1. CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
   2. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   3. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
   4. "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");                      
   5.                     
   6. CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>)
   7. ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
   8. LOCATION 's3://amzn-s3-demo-bucket/path/subpath/';
   9.                     
  10. INSERT OVERWRITE TABLE s3_export SELECT * 
  11. FROM hiveTableName;
  ```

**열 매핑을 지정하지 않고 DynamoDB 테이블을 Amazon S3 버킷으로 내보내는 방법**
+  DynamoDB에 저장된 데이터를 참조하는 Hive 테이블을 생성합니다. 열 매핑을 지정하지 않는다는 점을 제외하면 앞의 예제와 비슷합니다. 테이블에는 `map<string, string>` 형식의 열 1개만 있어야 합니다. Amazon S3에 `EXTERNAL` 테이블을 생성하면 `INSERT OVERWRITE` 명령을 직접 호출하여 DynamoDB에서 에 데이터를 쓸 수 있습니다. 이 항목을 사용하여 Amazon S3에서 DynamoDB 데이터의 아카이브를 생성할 수 있습니다. 열 매핑이 없으므로 이 방법으로 내보낸 테이블은 쿼리할 수 없습니다. Amazon EMR AMI 2.2.*x* 이상에서 지원되는 Hive 0.8.1.5 이상에서는 열 매핑을 지정하지 않고 데이터를 내보낼 수 있습니다.

  ```
   1. CREATE EXTERNAL TABLE hiveTableName (item map<string,string>)
   2. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   3. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1");  
   4.     
   5. CREATE EXTERNAL TABLE s3TableName (item map<string, string>)
   6. ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
   7. LOCATION 's3://amzn-s3-demo-bucket/path/subpath/'; 
   8.                 
   9. INSERT OVERWRITE TABLE s3TableName SELECT * 
  10. FROM hiveTableName;
  ```

**데이터 압축을 사용하여 DynamoDB 테이블을 Amazon S3 버킷으로 내보내는 방법**
+  Hive는 Hive 세션 중에 설정할 수 있는 여러 압축 코덱을 제공합니다. 그러면 내보낸 데이터가 지정된 형식으로 압축됩니다. 다음 예제에서는 Lempel-Ziv-Oberhumer(LZO) 알고리즘을 사용하여 내보낸 파일을 압축합니다.

  ```
   1. SET hive.exec.compress.output=true;
   2. SET io.seqfile.compression.type=BLOCK;
   3. SET mapred.output.compression.codec = com.hadoop.compression.lzo.LzopCodec;                    
   4.                     
   5. CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
   6. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   7. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
   8. "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");                    
   9.                     
  10. CREATE EXTERNAL TABLE lzo_compression_table (line STRING)
  11. ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
  12. LOCATION 's3://amzn-s3-demo-bucket/path/subpath/';
  13.                     
  14. INSERT OVERWRITE TABLE lzo_compression_table SELECT * 
  15. FROM hiveTableName;
  ```

   다음과 같은 압축 코덱을 사용할 수 있습니다.
  +  org.apache.hadoop.io.compress.GzipCodec 
  +  org.apache.hadoop.io.compress.DefaultCodec 
  +  com.hadoop.compression.lzo.LzoCodec 
  +  com.hadoop.compression.lzo.LzopCodec 
  +  org.apache.hadoop.io.compress.BZip2Codec 
  +  org.apache.hadoop.io.compress.SnappyCodec 

**DynamoDB 테이블을 HDFS로 내보내는 방법**
+  다음 Hive 명령을 사용합니다. 여기서 *hdfs:///directoryName*은 유효한 HDFS 경로이고 *hiveTableName*은 DynamoDB를 참조하는 Hive의 테이블입니다. Amazon S3로 데이터를 내보낼 때 Hive 0.7.1.1에서 HDFS를 중간 단계로 사용하므로 이 내보내기 작업은 DynamoDB 테이블을 Amazon S3로 내보내는 것보다 빠릅니다. 또한 다음 예제에서는 `dynamodb.throughput.read.percent`를 1.0으로 설정하여 읽기 요청 빈도를 높이는 방법을 보여 줍니다.

  ```
  1. CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
  2. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
  3. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
  4. "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays"); 
  5.                     
  6. SET dynamodb.throughput.read.percent=1.0;                    
  7.                     
  8. INSERT OVERWRITE DIRECTORY 'hdfs:///directoryName' SELECT * FROM hiveTableName;
  ```

   또한 Amazon S3로 내보내기 위해 위에 나온 대로 형식 및 압축을 사용하여 HDFS로 데이터를 내보낼 수 있습니다. 그러려면 위 예제의 Amazon S3 디렉터리를 HDFS 디렉터리로 바꾸기만 하면 됩니다.<a name="EMR_Hive_non-printable-utf8"></a>

**인쇄할 수 없는 UTF-8 문자 데이터를 Hive로 읽으려면**
+ 테이블을 생성할 때 `STORED AS SEQUENCEFILE` 절을 사용하여 인쇄할 수 없는 UTF-8 문자를 Hive로 읽고 쓸 수 있습니다. SequenceFile은 Hadoop 이진 파일 형식입니다. 이 파일을 읽으려면 Hadoop을 사용해야 합니다. 다음 예제에서는 DynamoDB에서 Amazon S3로 데이터를 내보내는 방법을 보여 줍니다. 이 기능을 사용하여 인쇄할 수 없는 UTF-8 인코딩 문자를 처리할 수 있습니다.

  ```
   1. CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
   2. STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
   3. TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
   4. "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");                      
   5.                     
   6. CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>)
   7. STORED AS SEQUENCEFILE
   8. LOCATION 's3://amzn-s3-demo-bucket/path/subpath/';
   9.                     
  10. INSERT OVERWRITE TABLE s3_export SELECT * 
  11. FROM hiveTableName;
  ```

## DynamoDB로 데이터 가져오기
<a name="EMR_Hive_Commands_importing"></a>

 Hive를 사용하여 DynamoDB에 데이터를 쓸 때 쓰기 용량 유닛 수가 클러스터의 매퍼 수보다 큰지 확인해야 합니다. 예를 들어, m1.xlarge EC2 인스턴스에서 실행되는 클러스터는 인스턴스당 8개의 매퍼를 생성합니다. 클러스터의 인스턴스가 10개일 경우 매퍼는 총 80개입니다. 쓰기 용량 단위가 클러스터의 매퍼 수보다 크지 않으면 Hive 쓰기 작업이 쓰기 처리량을 모두 소비하거나 프로비저닝된 것보다 많은 처리량을 소비하려고 합니다. 각 EC2 인스턴스 유형에서 생성되는 매퍼 수에 대한 자세한 내용은 [Hadoop 구성](emr-hadoop-config.md) 섹션을 참조하세요.

 Hadoop의 매퍼 수는 입력 분할로 제어됩니다. 분할이 너무 적으면 쓰기 명령이 사용 가능한 쓰기 처리량을 모두 사용하지 못할 수도 있습니다.

 동일한 키를 가진 항목이 대상 DynamoDB 테이블에 있으면 이 항목을 덮어씁니다. 해당 키를 가진 항목이 대상 DynamoDB 테이블에 없으면 항목이 삽입됩니다.

**Amazon S3에서 DynamoDB로 데이터를 가져오는 방법**
+  Amazon EMR(Amazon EMR) 및 Hive를 사용하여 Amazon S3에서 DynamoDB에 데이터를 쓸 수 있습니다.

  ```
  CREATE EXTERNAL TABLE s3_import(a_col string, b_col bigint, c_col array<string>)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
  LOCATION 's3://amzn-s3-demo-bucket/path/subpath/';                    
                      
  CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
  TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
  "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");  
                      
  INSERT OVERWRITE TABLE hiveTableName SELECT * FROM s3_import;
  ```

**열 매핑을 지정하지 않고 Amazon S3 버킷에서 DynamoDB로 테이블을 가져오는 방법**
+  전에 DynamoDB에서 내보내어 Amazon S3에 저장된 데이터를 참조하는 `EXTERNAL` 테이블을 생성합니다. 가져오기 전에 테이블이 DynamoDB에 있으며 전에 내보낸 DynamoDB 테이블과 동일한 키 스키마를 가지고 있는지 확인합니다. 또한 테이블에는 `map<string, string>` 형식의 열 1개만 있어야 합니다. DynamoDB에 연결된 Hive 테이블을 생성하면 `INSERT OVERWRITE` 명령을 호출하여 Amazon S3에서 DynamoDB에 데이터를 쓸 수 있습니다. 열 매핑이 없으므로 이 방법으로 가져온 테이블은 쿼리할 수 없습니다. Amazon EMR AMI 2.2.3 이상에서 지원되는 Hive 0.8.1.5 이상에서는 열 매핑을 지정하지 않고 데이터를 가져올 수 있습니다.

  ```
  CREATE EXTERNAL TABLE s3TableName (item map<string, string>)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
  LOCATION 's3://amzn-s3-demo-bucket/path/subpath/'; 
                          
  CREATE EXTERNAL TABLE hiveTableName (item map<string,string>)
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
  TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1");  
                   
  INSERT OVERWRITE TABLE hiveTableName SELECT * 
  FROM s3TableName;
  ```

**HDFS에서 DynamoDB로 테이블을 가져오는 방법**
+  Amazon EMR 및 Hive를 사용하여 HDFS에서 DynamoDB에 데이터를 쓸 수 있습니다.

  ```
  CREATE EXTERNAL TABLE hdfs_import(a_col string, b_col bigint, c_col array<string>)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
  LOCATION 'hdfs:///directoryName';                    
                      
  CREATE EXTERNAL TABLE hiveTableName (col1 string, col2 bigint, col3 array<string>)
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
  TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", 
  "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");  
                      
  INSERT OVERWRITE TABLE hiveTableName SELECT * FROM hdfs_import;
  ```

## DynamoDB의 데이터 쿼리
<a name="EMR_Hive_Commands_querying"></a>

 다음 예제에서는 Amazon EMR을 사용하여 DynamoDB에 저장된 데이터를 쿼리할 수 있는 여러 가지 방법을 보여줍니다.

**매핑된 열의 가장 큰 값을 찾으려면(`max`)**
+  다음과 같은 Hive 명령을 사용합니다. 첫 번째 명령에서 CREATE 문은 DynamoDB에 저장된 데이터를 참조하는 Hive 테이블을 생성합니다. 그러면 SELECT 문이 해당 테이블을 사용하여 DynamoDB에 저장된 데이터를 쿼리합니다. 다음 예제에서는 제공된 고객이 한 가장 큰 주문을 찾습니다.

  ```
  CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) 
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
  TBLPROPERTIES ("dynamodb.table.name" = "Purchases",
  "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items");
  
  SELECT max(total_cost) from hive_purchases where customerId = 717;
  ```

**`GROUP BY` 절을 사용하여 데이터를 집계하려면**
+  `GROUP BY` 절을 사용하여 여러 레코드에서 데이터를 수집할 수 있습니다. 이 절은 종종 sum, count, min 또는 max와 같은 집계 함수와 함께 사용됩니다. 다음 예제에서는 4번 이상 주문한 고객의 가장 큰 주문 목록을 반환합니다.

  ```
  CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) 
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
  TBLPROPERTIES ("dynamodb.table.name" = "Purchases",
  "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items");
  
  SELECT customerId, max(total_cost) from hive_purchases GROUP BY customerId HAVING count(*) > 3;
  ```

**두 DynamoDB 테이블을 조인하는 방법**
+  다음 예제에서는 Hive 테이블 2개를 DynamoDB에 저장된 데이터에 매핑합니다. 그러면 두 테이블에 조인이 호출됩니다. 조인은 클러스터에서 계산되어 반환됩니다. DynamoDB에서는 조인이 일어나지 않습니다. 이 예제에서는 고객 및 3번 이상 주문한 고객의 구매 목록이 반환합니다.

  ```
  CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) 
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
  TBLPROPERTIES ("dynamodb.table.name" = "Purchases",
  "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items");
  
  CREATE EXTERNAL TABLE hive_customers(customerId bigint, customerName string, customerAddress array<String>) 
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
  TBLPROPERTIES ("dynamodb.table.name" = "Customers",
  "dynamodb.column.mapping" = "customerId:CustomerId,customerName:Name,customerAddress:Address");
  
  Select c.customerId, c.customerName, count(*) as count from hive_customers c 
  JOIN hive_purchases p ON c.customerId=p.customerId 
  GROUP BY c.customerId, c.customerName HAVING count > 2;
  ```

**서로 다른 소스의 두 테이블을 조인하려면**
+  다음 예제에서 Customer\$1S3는 Amazon S3에 저장된 CSV 파일을 로드하는 Hive 테이블이며, hive\$1purchases는 DynamoDB의 데이터를 참조하는 테이블입니다. 다음 예제에서는 Amazon S3에 CSV 파일로 저장된 고객 데이터를 DynamoDB에 저장된 주문 데이터와 조인하여 이름에 'Miller'가 포함된 고객이 한 주문을 나타내는 데이터 세트를 반환합니다.

  ```
  CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) 
  STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
  TBLPROPERTIES ("dynamodb.table.name" = "Purchases",
  "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items");
  
  CREATE EXTERNAL TABLE Customer_S3(customerId bigint, customerName string, customerAddress array<String>)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
  LOCATION 's3://amzn-s3-demo-bucket/path/subpath/';
  
  Select c.customerId, c.customerName, c.customerAddress from 
  Customer_S3 c 
  JOIN hive_purchases p 
  ON c.customerid=p.customerid 
  where c.customerName like '%Miller%';
  ```

**참고**  
 위의 예제에서 명확성과 완성도를 위해 CREATE TABLE 문이 각 예제에 포함되었습니다. 제공된 Hive 테이블에 대해 여러 쿼리나 내보내기 작업을 실행할 때는 Hive 세션을 시작할 때 한 번만 테이블을 생성해야 합니다.

# DynamoDB에서 Amazon EMR 작업 성능 최적화
<a name="EMR_Hive_Optimizing"></a>

 DynamoDB 테이블에서 Amazon EMR 작업은 읽기 작업으로 간주되어 테이블의 프로비저닝 처리량 설정이 적용됩니다. Amazon EMR은 프로비저닝된 처리량을 초과할 가능성을 최소화하기 위해 DynamoDB 테이블의 부하를 균형 있게 분산시키려는 자체 로직을 구현합니다. 각 Hive 쿼리가 끝날 때마다 Amazon EMR이 프로비저닝 처리량의 초과 횟수를 포함해 쿼리 처리에 사용된 클러스터 정보를 반환합니다. 이 정보는 DynamoDB 처리량에 대한 CloudWatch 지표와 함께 후속 요청에서 DynamoDB 테이블에 대한 로드를 효과적으로 관리하는 데 사용됩니다.

 다음은 DynamoDB 테이블 작업 시 Hive 쿼리 성능에 영향을 미치는 요인입니다.

## 프로비저닝된 읽기 용량 유닛
<a name="ProvisionedReadCapacityUnits"></a>

 DynamoDB 테이블에 대해 Hive 쿼리를 실행하는 경우 충분한 양의 읽기 용량 유닛을 프로비저닝했는지 확인해야 합니다.

 예를 들어, DynamoDB 테이블에 읽기 용량 단위를 100개 프로비저닝하였다고 가정하겠습니다. 그러면 초당 100회의 읽기(또는 409,600바이트)를 수행할 수 있습니다. 테이블에 20GB의 데이터(21,474,836,480바이트)가 포함되어 있고 Hive 쿼리에서 전체 테이블 스캔을 수행하는 경우 쿼리를 실행하는 데 걸리는 시간을 추산할 수 있습니다.

 * 21,474,836,480 / 409,600 = 52,429초 = 14.56시간 * 

 필요한 시간을 줄일 수 있는 유일한 방법은 원본 DynamoDB 테이블에서 읽기 용량 유닛을 조정하는 것입니다. 노드를 Amazon EMR 클러스터에 더 추가하더라도 효과가 없습니다.

 Hive 출력에서 하나 이상의 매퍼 프로세스가 완료되면 진행률이 업데이트됩니다. 하지만 대용량 DynamoDB 테이블에서 프로비저닝된 읽기 용량이 낮게 설정된 경우에는 진행률 출력이 오랫동안 업데이트되지 않을 수도 있습니다. 위 경우에는 작업 진행률이 몇 시간 0%로 표시됩니다. 작업 진행률에 대한 자세한 상태를 보려면 Amazon EMR 콘솔로 이동하여 개별 매퍼 작업 상태와 데이터 읽기에 대한 통계를 볼 수 있습니다.

 마스터 노드에서 Hadoop 인터페이스에 로그온하여 Hadoop 통계를 볼 수도 있습니다. 여기에는 개별 맵 작업 상태와 일부 데이터 읽기 통계가 표시됩니다. 자세한 내용은 *Amazon EMR 관리 안내서*에서 [프라이머리 노드에 호스팅된 웹 인터페이스](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-web-interfaces.html)를 참조하세요.

## 읽기 비율 설정
<a name="ReadPercent"></a>

 기본적으로 Amazon EMR은 현재 프로비저닝된 처리량에 따라 DynamoDB 테이블에 대한 요청 로드를 관리합니다. 하지만 Amazon EMR이 반환하는 작업 정보에 프로비저닝된 처리량을 초과하는 높은 응답 수가 포함된 경우 Hive 테이블을 설정하면서 `dynamodb.throughput.read.percent` 파라미터를 사용해 기본 읽기 비율을 조정할 수 있습니다. 읽기 비율 파라미터 설정에 대한 자세한 내용은 [Hive 옵션](EMR_Interactive_Hive.md#EMR_Hive_Options) 섹션을 참조하세요.

## 쓰기 비율 설정
<a name="WritePercent"></a>

 기본적으로 Amazon EMR은 현재 프로비저닝된 처리량에 따라 DynamoDB 테이블에 대한 요청 로드를 관리합니다. 하지만 Amazon EMR이 반환하는 작업 정보에 프로비저닝된 처리량을 초과하는 높은 응답 수가 포함된 경우 Hive 테이블을 설정하면서 `dynamodb.throughput.write.percent` 파라미터를 사용해 기본 쓰기 비율을 조정할 수 있습니다. 쓰기 비율 파라미터 설정에 대한 자세한 내용은 [Hive 옵션](EMR_Interactive_Hive.md#EMR_Hive_Options) 섹션을 참조하세요.

## 재시도 지속 시간 설정
<a name="emr-ddb-retry-duration"></a>

 기본적으로 Amazon EMR은 기본 재시도 주기인 2분 내에 결과를 반환하지 않으면 Hive 쿼리를 다시 실행합니다. 이 주기는 Hive 쿼리 실행 시 `dynamodb.retry.duration` 파라미터를 설정하면 조정 가능합니다. 쓰기 비율 파라미터 설정에 대한 자세한 내용은 [Hive 옵션](EMR_Interactive_Hive.md#EMR_Hive_Options) 섹션을 참조하세요.

## 맵 작업 수
<a name="NumberMapTasks"></a>

 DynamoDB에 저장된 데이터 내보내기 및 쿼리 요청을 처리할 목적으로 Hadoop에서 실행하는 매퍼 대몬(daemon)은 최대 읽기 비율이 초당 1MiB이기 때문에 사용할 수 있는 읽기 용량도 제한됩니다. 이때 DynamoDB에서 사용할 수 있는 프로비저닝된 처리량을 추가하면 매퍼 대몬(daemon) 수를 늘려 Hive 내보내기 및 쿼리 작업 성능을 높일 수 있습니다. 이를 위해 클러스터에 속한 EC2 인스턴스 수를 늘릴 수 있습니다. *또는* 각 EC2 인스턴스에서 실행되는 매퍼 대몬(daemon) 수를 늘릴 수 있습니다.

 클러스터의 EC2 인스턴스 수를 늘리려면 현재 클러스터를 중단하고 EC2 인스턴스 수를 늘려 재실행하면 됩니다. Amazon EMR 콘솔을 사용해 클러스터를 시작한 경우에는 **EC2 인스턴스 구성** 대화 상자에서 EC2 인스턴스 수를 지정합니다. 또는 CLI에서 클러스터를 시작한 경우에는 `‑‑num-instances` 옵션을 통해 EC2 인스턴스 수를 지정합니다.

 인스턴스에서 실행되는 맵 작업 수는 EC2 인스턴스 유형에 따라 다릅니다. 지원되는 EC2 인스턴스 유형과 각 인스턴스가 제공하는 매퍼 수에 대한 자세한 내용은 [작업 구성](emr-hadoop-task-config.md) 섹션을 참조하세요. 여기에서 "작업 구성(Task Configuration)" 섹션을 보면 각각 지원되는 구성을 알 수 있습니다.

 매퍼 대몬의 수를 늘리는 또 한 가지 방법은 Hadoop의 `mapreduce.tasktracker.map.tasks.maximum` 구성 파라미터 값을 높이는 것입니다. 이 방법은 EC2 인스턴스 수나 크기를 늘리지 않고 매퍼를 추가함으로써 비용을 절감한다는 점에서 이점이 있습니다. 반면에 이 값을 너무 높게 설정하면 클러스터에 속한 EC2 인스턴스의 메모리가 부족할 수도 있다는 것이 단점입니다. `mapreduce.tasktracker.map.tasks.maximum`을 설정하려면 클러스터를 시작하고 mapred-site 구성 분류의 속성으로 `mapreduce.tasktracker.map.tasks.maximum`의 값을 지정합니다. 방법은 다음 예제와 같습니다. 자세한 내용은 [애플리케이션 구성](emr-configure-apps.md) 단원을 참조하십시오.

```
{
    "configurations": [
    {
        "classification": "mapred-site",
        "properties": {
            "mapred.tasktracker.map.tasks.maximum": "10"
        }
    }
    ]
}
```

## 병렬 데이터 요청
<a name="ParallelDataRequests"></a>

 한 명 이상의 사용자 또는 하나 이상의 애플리케이션에서 단일 테이블로 데이터 요청이 다수 이루어지면 읽기 프로비저닝 처리량이 한 번에 소모되어 성능이 느려질 수 있습니다.

## 프로세스 기간
<a name="ProcessDuration"></a>

 DynamoDB의 데이터 일관성은 각 노드의 읽기 및 쓰기 작업 순서에 따라 달라집니다. Hive 쿼리가 진행 중일 때는 다른 애플리케이션이 새로운 데이터를 DynamoDB 테이블에 로드하거나 기존 데이터를 변경 또는 삭제하기도 합니다. 이 경우 쿼리 실행 중 데이터 변경 사항은 Hive 쿼리 결과에 반영되지 않습니다.

## 처리량 초과 주의
<a name="AvoidExceedingThroughput"></a>

 DynamoDB에 대해 Hive 쿼리를 실행할 때는 프로비저닝된 처리량을 초과하지 않도록 주의해야 합니다. 그렇지 않으면 애플리케이션이 `DynamoDB::Get`을 직접 호출하는 데 필요한 용량이 고갈되기 때문입니다. 이러한 용량 고갈을 방지하려면 Amazon CloudWatch의 로그를 점검하고 메트릭을 관찰하여 `DynamoDB::Get` 애플리케이션 호출에 따른 읽기 볼륨 및 병목 현상을 정기적으로 모니터링해야 합니다.

## 요청 시간
<a name="RequestTime"></a>

 DynamoDB 테이블에 대한 수요가 낮은 시간에 Hive 쿼리가 DynamoDB 테이블에 액세스하도록 일정을 조정하면 성능이 향상됩니다. 예를 들어, 애플리케이션 사용자 대부분이 샌프란시스코에 거주한다면 대다수가 잠드는 시간인 새벽 4시(PST)에 DynamoDB 데이터베이스의 레코드 업데이트 없이 일일 데이터를 내보내도록 선택할 수 있습니다.

## 시간 기반 테이블
<a name="TimeBasedTables"></a>

 데이터가 1일 1개 테이블처럼 시간 기반 DynamoDB 테이블의 형태로 구성되는 경우에는 테이블이 활성 상태가 아닐 때 데이터를 내보낼 수 있습니다. 이 기술은 데이터를 Amazon S3에 지속적으로 백업할 때 사용됩니다.

## 아카이브된 데이터
<a name="ArchivedData"></a>

 DynamoDB에 저장된 데이터에 대해 Hive 쿼리를 여러 차례 실행할 계획이면서 애플리케이션이 데이터 아카이브를 허용하는 경우에는 데이터를 HDFS 또는 Amazon S3로 내보내서 DynamoDB가 아닌 데이터 사본에 대해 Hive 쿼리를 실행할 수 있습니다. 그러면 읽기 작업과 프로비저닝 처리량이 절약됩니다.