DynamoDB에서 데이터 내보내기, 가져오기 및 쿼리를 위한 Hive 명령 예제 - Amazon EMR

DynamoDB에서 데이터 내보내기, 가져오기 및 쿼리를 위한 Hive 명령 예제

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

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

Hive 명령 DROP TABLECREATE TABLE은 Hive의 로컬 테이블에만 적용되며 DynamoDB에서 테이블을 생성하거나 삭제하지 않습니다. Hive 쿼리가 DynamoDB의 테이블을 참조할 경우 쿼리를 실행하기 전에 해당 테이블이 이미 있어야 합니다. DynamoDB에서 테이블을 생성하고 삭제하는 방법에 대한 자세한 내용은 Amazon DynamoDB 개발자 안내서에서 DynamoDB의 테이블 작업을 참조하세요.

참고

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

DynamoDB에서 데이터 내보내기

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

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

    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 DIRECTORY 's3://amzn-s3-demo-bucket/path/subpath/' SELECT * FROM hiveTableName;
형식을 사용하여 DynamoDB 테이블을 Amazon S3 버킷으로 내보내는 방법
  • Amazon S3 내 위치를 참조하는 외부 테이블을 생성합니다. 이 작업은 s3_export로 아래에 표시됩니다. CREATE 호출 중에 테이블의 행 형식을 지정합니다. 그러면 INSERT OVERWRITE를 사용하여 DynamoDB에서 s3_export로 데이터를 내보낼 때 지정된 형식으로 데이터가 쓰여집니다. 다음 예제에서는 쉼표로 구분된 값(CSV)으로 데이터가 쓰여집니다.

    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"); CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://amzn-s3-demo-bucket/path/subpath/'; INSERT OVERWRITE TABLE s3_export SELECT * 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 이상에서는 열 매핑을 지정하지 않고 데이터를 내보낼 수 있습니다.

    CREATE EXTERNAL TABLE hiveTableName (item map<string,string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1"); 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/'; INSERT OVERWRITE TABLE s3TableName SELECT * FROM hiveTableName;
데이터 압축을 사용하여 DynamoDB 테이블을 Amazon S3 버킷으로 내보내는 방법
  • Hive는 Hive 세션 중에 설정할 수 있는 여러 압축 코덱을 제공합니다. 그러면 내보낸 데이터가 지정된 형식으로 압축됩니다. 다음 예제에서는 Lempel-Ziv-Oberhumer(LZO) 알고리즘을 사용하여 내보낸 파일을 압축합니다.

    SET hive.exec.compress.output=true; SET io.seqfile.compression.type=BLOCK; SET mapred.output.compression.codec = com.hadoop.compression.lzo.LzopCodec; 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"); CREATE EXTERNAL TABLE lzo_compression_table (line STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' LOCATION 's3://amzn-s3-demo-bucket/path/subpath/'; INSERT OVERWRITE TABLE lzo_compression_table SELECT * 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으로 설정하여 읽기 요청 빈도를 높이는 방법을 보여 줍니다.

    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"); SET dynamodb.throughput.read.percent=1.0; INSERT OVERWRITE DIRECTORY 'hdfs:///directoryName' SELECT * FROM hiveTableName;

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

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

    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"); CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>) STORED AS SEQUENCEFILE LOCATION 's3://amzn-s3-demo-bucket/path/subpath/'; INSERT OVERWRITE TABLE s3_export SELECT * FROM hiveTableName;

DynamoDB로 데이터 가져오기

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

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

동일한 키를 가진 항목이 대상 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의 데이터 쿼리

다음 예제에서는 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_S3는 Amazon S3에 저장된 CSV 파일을 로드하는 Hive 테이블이며, hive_purchases는 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 세션을 시작할 때 한 번만 테이블을 생성해야 합니다.