Amazon EMR에서 Hive의 차이점 및 고려 사항
Amazon EMR의 Apache Hive와 Apache Hive 간의 차이점
이 섹션에서는 Amazon EMR의 Hive와 http://svn.apache.org/viewvc/hive/branches/
Hive 권한 부여
Amazon EMR은 HDFS에 대해 Hive 권한 부여
Amazon S3와 Hive 파일 병합 동작
Apache Hive는 hive.merge.mapfiles
가 true이고 작업의 평균 출력 크기가 hive.merge.smallfiles.avgsize
설정보다 작은 경우에만 병합이 트리거되면 맵 전용 작업의 끝에서 작은 파일을 병합합니다. Amazon EMR Hive는 최종 출력 경로가 HDFS에 있는 경우 정확히 동일한 동작을 수행합니다. 출력 경로가 Amazon S3에 있는 경우 hive.merge.smallfiles.avgsize
파라미터는 무시됩니다. 이 상황에서 hive.merge.mapfiles
가 true
로 설정된 경우 병합 작업이 항상 트리거됩니다.
ACID 트랜잭션 및 Amazon S3
Amazon EMR 6.1.0 이상에서는 Hive 원자성, 일관성, 격리성, 내구성(ACID) 트랜잭션을 지원하므로 데이터베이스의 ACID 속성을 준수합니다. 이 기능을 사용하면 Amazon Simple Storage Service(S3)의 데이터를 사용하여 Hive 관리형 테이블에서 INSERT, UPDATE, DELETE, MERGE 작업을 실행할 수 있습니다.
Hive LLAP(Live Long and Process)
기본 Apache Hive 버전 2.0에서 추가된 LLAP 기능
Amazon EMR 버전 6.0.0 이상에서는 Hive용 LLAP(Live Long and Process) 기능을 지원합니다. 자세한 내용은 Hive LLAP 사용을 참조하십시오.
Amazon EMR 릴리스 버전 4.x 및 5.x 간 Hive의 차이
이 섹션에서는 Amazon EMR 릴리스 4.x의 Hive 버전 1.0.0에서 Amazon EMR 릴리스 5.x의 Hive 2.x로 Hive 구현을 마이그레이션하기 전에 고려해야 할 차이점을 설명합니다.
작업 차이점 및 고려 사항
원자성, 일관성, 격리성, 내구성(ACID) 트랜잭션
에 대한 지원이 추가됨: Amazon EMR 4.x의 Hive 1.0.0 및 기본 Apache Hive 간의 이 차이점이 제거되었습니다. Amazon S3에 대한 직접 쓰기가 제거됨: Amazon EMR의 Hive 1.0.0과 기본 Apache Hive 간의 이 차이점이 제거되었습니다. 이제 Amazon EMR 릴리스 5.x의 Hive 2.1.0이 Amazon S3에 저장된 임시 파일을 생성하고, 해당 파일에서 읽고 해당 파일에 씁니다. 결과적으로 같은 테이블에서 읽고 쓰기 위해 차선책으로 임시 테이블을 클러스터의 로컬 HDFS 파일 시스템에 만들 필요가 더 이상 없습니다. 버전이 지정된 버킷을 사용하는 경우 아래 설명한 대로 이러한 임시 파일을 관리해야 합니다.
Amazon S3 버전 지정된 버킷을 사용하는 경우 임시 파일 관리: 생성된 데이터의 대상이 Amazon S3인 Hive 쿼리를 실행하면 많은 임시 파일과 디렉터리가 생성됩니다. 앞에서 설명한대로 새로운 동작입니다. 버전 지정된 S3 버킷을 사용하는 경우 이러한 임시 파일은 Amazon S3를 복잡하게 만들며, 이를 삭제하지 않으면 비용이 발생합니다. 짧은 기간(예: 5일) 후에
/_tmp
접두사가 있는 데이터가 삭제되도록 수명 주기 규칙을 조정하십시오. 자세한 내용은 수명 주기 구성 지정을 참조하세요.Log4j가 log4j 2로 업데이트됨: log4j를 사용하는 경우 이 업그레이드로 인해 로깅 구성을 변경해야 할 수 있습니다. 자세한 내용은 Apache log4j 2
를 참조하십시오.
성능 차이점 및 고려사항
Tez의 성능 차이점: Amazon EMR 릴리스 5.x에서 Tez는 MapReduce 대신 Hive의 기본 실행 엔진입니다. Tez은 대부분의 워크플로에서 개선된 성능을 제공합니다.
파티션이 많은 테이블: 많은 수의 동적 파티션을 생성하는 쿼리는 실패할 수 있으며 많은 파티션이 있는 테이블에서 선택하는 쿼리는 실행하는 데 예상보다 오래 걸릴 수 있습니다. 예를 들어, 100,000 개의 파티션 중에서 선택하려면 10분 이상 걸릴 수 있습니다.
Amazon EMR에서 Hive의 추가 기능
Amazon EMR은 Amazon Simple Storage Service(S3) 및 DynamoDB에 대한 읽기 및 쓰기 기능과 같이, Hive와 다른 AWS 서비스의 통합을 지원하는 새 기능을 추가하여 Hive를 확장합니다.
Hive의 변수
달러 기호와 중괄호를 사용하여 스크립트에 변수를 포함할 수 있습니다.
add jar ${LIB}/jsonserde.jar
다음 예제와 같이 -d
파라미터를 사용하여 명령줄에서 이러한 변수의 값을 Hive로 전달할 수 있습니다.
-d LIB=s3://elasticmapreduce/samples/hive-ads/lib
또한 Hive 스크립트를 실행하는 단계로 값을 전달할 수 있습니다.
콘솔을 사용하여 변수 값을 Hive 단계로 전달하려면
https://console.aws.amazon.com/emr
에서 Amazon EMR 콘솔을 엽니다. -
클러스터 생성을 선택합니다.
-
Steps(단계) 섹션의 Add Step(단계 추가)에 있는 목록에서 Hive Program(Hive 프로그램)을 선택하고 Configure and add(구성 및 추가)를 선택합니다.
-
Add Step(단계 추가) 대화 상자에서 다음 표를 가이드로 사용하여 파라미터를 지정한 다음 Add(추가)를 선택합니다.
필드 작업 Script S3 location* 스크립트가 위치한 Amazon S3의 URI를 지정합니다. 값은 BucketName
/path
/ScriptName
형식이어야 합니다. 예:s3://elasticmapreduce/samples/hive-ads/libs/response-time-stats.q
.Input S3 location 선택적으로 입력 파일이 위치한 Amazon S3의 URI를 지정합니다. 값은 BucketName
/path
/ 형식이어야 합니다. 지정된 경우 이 값은 Hive 스크립트에INPUT
이름의 파라미터로 전달됩니다. 예:s3://elasticmapreduce/samples/hive-ads/tables/
.Output S3 location 선택적으로 출력을 저장할 Amazon S3의 URI를 지정합니다. 값은 BucketName
/path
형식이어야 합니다. 지정된 경우 이 값은 Hive 스크립트에OUTPUT
이름의 파라미터로 전달됩니다. 예:s3://amzn-s3-demo-bucket/hive-ads/output/
.인수 또는 Hive에 전달할 인수 목록(공백으로 구분된 문자열)을 입력합니다. ${SAMPLE} 이름의 경로 변수를 Hive 스크립트에 정의한 경우, 예를 들면 다음과 같습니다. CREATE EXTERNAL TABLE logs (requestBeginTime STRING, requestEndTime STRING, hostname STRING) PARTITIONED BY (dt STRING) \ ROW FORMAT serde 'com.amazon.elasticmapreduce.JsonSerde' WITH SERDEPROPERTIES ( 'paths'='requestBeginTime, requestEndTime, hostname' ) LOCATION '${SAMPLE}/tables/impressions';
변수 값을 전달하려면 Arguments(인수) 창에 다음을 입력합니다.
-d SAMPLE=s3://elasticmapreduce/samples/hive-ads/
.Action on Failure 이 옵션은 오류 발생 시 클러스터가 수행해야 할 동작을 결정합니다. 이 설정에 사용할 수 있는 값은 다음과 같습니다.
-
클러스터 종료: 단계가 실패할 경우 클러스터를 종료합니다. 클러스터에 종료 방지 기능과 연결 유지 기능이 활성화된 경우에는 클러스터가 종료되지 않습니다.
-
취소 및 대기: 단계가 실패할 경우 남은 단계를 취소합니다. 클러스터에 연결 유지 기능이 활성화된 경우에는 클러스터가 종료되지 않습니다.
-
계속: 단계가 실패할 경우 다음 단계가 계속 수행됩니다.
-
-
필요에 따라 값을 선택하고 Create cluster(클러스터 생성)를 선택합니다.
AWS CLI를 사용하여 변수 값을 Hive 단계로 전달하는 방법
AWS CLI를 사용하여 변수 값을 Hive 단계로 전달하려면 --steps
파라미터를 사용하고 인수 목록을 포함합니다.
-
참고
가독성을 위해 Linux 줄 연속 문자(\)가 포함됩니다. Linux 명령에 사용하거나 제외할 수 있습니다. Windows에서는 제외시키거나 캐럿(^)으로 바꿉니다.
aws emr create-cluster --name "
Test cluster
" --release-labelemr-7.3.0
\ --applications Name=Hive
Name=Pig
--use-default-roles --ec2-attributes KeyName=myKey
--instance-typem5.xlarge
--instance-count3
\ --steps Type=Hive
,Name="Hive Program
",ActionOnFailure=CONTINUE
,Args=[-f,s3://elasticmapreduce/samples/hive-ads/libs/response-time-stats.q
,-d,INPUT=s3://elasticmapreduce/samples/hive-ads/tables
,-d,OUTPUT=s3://amzn-s3-demo-bucket/hive-ads/output/
,-d,SAMPLE
=s3://elasticmapreduce/samples/hive-ads/
]AWS CLI에서 Amazon EMR 명령 사용에 대한 자세한 내용은 https://docs.aws.amazon.com/cli/latest/reference/emr 섹션을 참조하세요.
Java SDK;를 사용하여 변수 값을 Hive 단계로 전달하려면
-
다음 예에서는 SDK를 사용하여 변수를 단계에 전달하는 방법을 보여 줍니다. 자세한 내용은 AWS SDK for Java API 참조에서 Class StepFactory를 참조하세요.
StepFactory stepFactory = new StepFactory(); StepConfig runHive = new StepConfig() .withName("Run Hive Script") .withActionOnFailure("TERMINATE_JOB_FLOW") .withHadoopJarStep(stepFactory.newRunHiveScriptStep(“s3://amzn-s3-demo-bucket/script.q”, Lists.newArrayList(“-d”,”LIB= s3://elasticmapreduce/samples/hive-ads/lib”));
부분 DynamoDB 스키마를 수용할 Amazon EMR Hive 쿼리
Amazon EMR Hive는 쿼리에 모든 열을 포함하지 않아도 데이터를 필터링할 수 있는 열 하위 세트를 지정할 수 있도록 함으로써 DynamoDB 테이블 쿼리 시 최대 유연성을 제공합니다. 이 부분 스키마 쿼리 기술은 스파스 데이터베이스 스키마가 있고 타임스탬프 필터링 같은 몇 개 열에 기초하여 레코드를 필터링해야 하는 경우에 효과적입니다.
다음 예제에서는 Hive 쿼리를 사용하여 다음을 수행하는 방법을 보여 줍니다.
-
DynamoDB 테이블을 생성합니다.
-
DynamoDB에서 항목 하위 세트(행)를 선택하고 데이터의 범위를 특정 열로 좁힙니다.
-
결과 데이터를 Amazon S3에 복사합니다.
DROP TABLE dynamodb; DROP TABLE s3; CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, fullColumn map<String, String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.throughput.read.percent" = ".1000", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey"); CREATE EXTERNAL TABLE s3(map<String, String>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE s3 SELECT item fullColumn FROM dynamodb WHERE recordTimeStamp < "2012-01-01";
다음 테이블에는 DynamoDB에서 임의의 항목 조합을 선택하기 위한 쿼리 구문이 표시됩니다.
쿼리 예제 | 결과 설명 |
---|---|
SELECT * FROM table_name ; |
해당 테이블에서 모든 항목(행)을 선택하고 이러한 항목에 사용할 수 있는 모든 열의 데이터를 포함합니다. |
SELECT * FROM table_name WHERE field_name =value ; |
해당 테이블에서 일부 항목(행)을 선택하고 이러한 항목에 사용할 수 있는 모든 열의 데이터를 포함합니다. |
SELECT column1_name , column2_name , column3_name FROM table_name ; |
해당 테이블에서 모든 항목(행)을 선택하고 이러한 항목에 사용할 수 있는 일부 열의 데이터를 포함합니다. |
SELECT column1_name , column2_name , column3_name FROM table_name WHERE field_name =value ; |
해당 테이블에서 일부 항목(행)을 선택하고 이러한 항목에 사용할 수 있는 일부 열의 데이터를 포함합니다. |
다양한 AWS 리전의 DynamoDB 테이블 간에 데이터 복사
Amazon EMR Hive는 DynamoDB 테이블마다 설정할 수 있는 dynamodb.region
속성을 제공합니다. dynamodb.region
을 두 테이블에서 서로 다르게 설정할 경우 테이블 간에 복사하는 모든 데이터가 지정된 리전 사이에서 자동으로 발생합니다.
다음 예제에서는 dynamodb.region
속성을 설정하는 Hive 스크립트를 사용하여 DynamoDB 테이블을 생성하는 방법을 보여줍니다.
참고
테이블당 리전 속성은 전역 Hive 속성을 재정의합니다.
CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, map<String, String> fullColumn) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.region" = "eu-west-1", "dynamodb.throughput.read.percent" = ".1000", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey");
테이블당 DynamoDB 처리량 값 설정
Amazon EMR Hive를 사용하면 테이블 정의에서 테이블 단위로 DynamoDB readThroughputPercent 및 writeThroughputPercent 설정을 지정할 수 있습니다. 다음 Amazon EMR Hive 스크립트는 처리량 값을 설정하는 방법을 보여줍니다. DynamoDB 처리량 값에 대한 자세한 내용은 테이블의 읽기/쓰기 요건 지정을 참조하세요.
CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, map<String, String> fullColumn) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.throughput.read.percent" = ".4", "dynamodb.throughput.write.percent" = "1.0", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey");