데이터 파티셔닝 - Amazon Athena

데이터 파티셔닝

데이터를 분할하면 각 쿼리가 스캔하는 데이터의 양을 제한하여 성능을 향상시키고 비용을 절감할 수 있습니다. 어떤 키를 기준으로도 데이터를 분할할 수 있습니다. 일반적으로 시간을 기준으로 데이터가 분할되어, 다중 레벨 파티셔닝 체계가 형성되는 경우가 많습니다. 예를 들어, 매시간 데이터를 수집하는 고객은 연, 월, 일, 시를 기준으로 분할할 수 있습니다. 다양한 소스로부터 데이터를 수집하되 하루에 한 번만 로드하는 고객의 경우 데이터 원본 식별자 및 날짜별로 분할할 수 있습니다.

Athena는 Apache Hive 스타일 파티션을 사용할 수 있습니다. 이 파티션의 데이터 경로에 등호로 연결된 키 값 페어가 포함되어 있습니다(예: country=us/... 또는 year=2021/month=01/day=26/...). 따라서 경로에는 파티션 키의 이름과 각 경로가 나타내는 값이 모두 포함됩니다. 파티션을 나눈 테이블에 새 Hive 파티션을 로드하려면 MSCK REPAIR TABLE 명령을 사용할 수 있으며 이 명령은 Hive 스타일 파티션에서만 작동합니다.

Athena는 비 Hive 스타일 파티션 체계를 사용할 수도 있습니다. 예를 들어 CloudTrail 로그 및 Firehose 전송 스트림은 data/2021/01/26/us/6fc7845e.json와 같은 날짜 부분에 대해 별도의 경로 구성 요소를 사용합니다. Hive와 호환되지 않는 데이터의 경우 ALTER TABLE ADD PARTITION을(를) 사용하여 파티션을 수동으로 추가합니다.

고려 사항 및 제한

파티셔닝을 사용할 때는 다음 사항에 유의하세요.

  • WHERE 절에서 분할된 테이블을 쿼리하고 파티션을 지정하면 Athena는 해당 파티션의 데이터만 검색합니다.

  • 객체가 많은 Amazon S3 버킷에 대해 쿼리를 실행하는데 데이터가 분할되지 않은 경우, 그러한 쿼리는 Amazon S3의 GET 요청 빈도 제한에 영향을 주고 Amazon S3 예외를 발생시킬 수 있습니다. 오류를 방지하려면 데이터를 분할하세요. 또한 Amazon S3 요청 빈도를 조정합니다. 자세한 내용은 모범 사례 설계 패턴: Amazon S3 성능 최적화를 참조하세요.

  • Athena에 사용될 파티션 위치는 s3 프로토콜(예: s3://amzn-s3-demo-bucket/folder/)을 사용해야 합니다. Athena에서, 다른 프로토콜(예: s3a://amzn-s3-demo-bucket/folder/)을 사용하는 위치는 포함 테이블에서 MSCK REPAIR TABLE 쿼리를 실행할 때 쿼리 실패를 초래하게 됩니다.

  • Amazon S3 경로가 camel 표기 대신 소문자인지 확인합니다(예: userId 대신 userid). S3 경로가 camel 표기인 경우 MSCK REPAIR TABLE은 AWS Glue Data Catalog에 파티션을 추가하지 않습니다. 자세한 내용은 MSCK REPAIR TABLE 단원을 참조하십시오.

  • MSCK REPAIR TABLE은 일치하는 파티션 스키마를 찾기 위해 폴더와 하위 폴더를 모두 스캔하기 때문에 별도의 폴더 계층 구조에 있는 별도의 테이블에 데이터를 보관해야 합니다. 예를 들어 테이블 1의 데이터를 s3://amzn-s3-demo-bucket1에 두고 테이블 2에 대한 데이터을 s3://amzn-s3-demo-bucket1/table-2-data에 두었다고 가정합시다. 두 테이블이 모두 문자열로 분할된 경우 MSCK REPAIR TABLE은 테이블 2의 파티션을 테이블 1에 추가합니다. 이를 방지하려면 대신에 s3://amzn-s3-demo-bucket1s3://amzn-s3-demo-bucket2와 같은 별도의 폴더 구조를 사용하세요. 이 동작은 Amazon EMR과 Apache Hive에서도 동일합니다.

  • Athena와 함께 AWS Glue Data Catalog를 사용하는 경우 계정 및 테이블당 파티션의 서비스 할당량은 AWS Glue 엔드포인트 및 할당량을 참조하세요.

    • Athena는 1천만 개의 파티션이 있는 AWS Glue 테이블에 대한 쿼리를 지원하지만, 단일 스캔으로 1백만 개 이상의 파티션을 읽을 수는 없습니다. 이러한 시나리오에서는 파티션 인덱싱이 유용할 수 있습니다. 자세한 내용을 알아보려면 AWS Big Data Blog(빅 데이터 블로그) 문서인 Improve Amazon Athena query performance using AWS Glue Data Catalog partition indexes(파티션 인덱스를 사용하여 Amazon Athena 쿼리 성능 향상)를 참조하세요.

  • AWS Glue Data Catalog를 사용하는 경우 파티션 할당량 증가를 요청하려면 AWS Glue의 Service Quotas 콘솔을 방문하세요.

분할된 데이터로 테이블 생성 및 로드

파티션을 사용하는 테이블을 생성하려면 CREATE TABLE 문에 PARTITIONED BY 절을 사용합니다. PARTITIONED BY 절은 다음 예와 같이 데이터를 분할하는 키를 정의합니다. LOCATION 절은 분할된 데이터의 루트 위치를 지정합니다.

CREATE EXTERNAL TABLE users ( first string, last string, username string ) PARTITIONED BY (id string) STORED AS parquet LOCATION 's3://amzn-s3-demo-bucket'

테이블을 생성한 후 쿼리를 위해 파티션에 데이터를 로드합니다. Hive 스타일 파티션의 경우, MSCK REPAIR TABLE을(를) 실행합니다. Hive 스타일이 아닌 파티션의 경우, ALTER TABLE ADD PARTITION을(를) 사용하여 파티션을 수동으로 추가합니다.

쿼리를 위해 Hive 스타일 및 비 Hive 스타일 데이터 준비

다음 섹션에서는 Athena에서 쿼리하기 위해 Hive 스타일 및 비 Hive 스타일 데이터를 준비하는 방법을 보여줍니다.

이 시나리오에서는 Amazon S3에 있는 별도의 폴더에 파티션이 저장됩니다. 예를 들어 다음은 지정된 접두사 아래에 S3 객체를 나열하는 aws s3 ls 명령으로 출력된 샘플 광고 노출에 대한 부분 목록입니다.

aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/ PRE dt=2009-04-12-13-00/ PRE dt=2009-04-12-13-05/ PRE dt=2009-04-12-13-10/ PRE dt=2009-04-12-13-15/ PRE dt=2009-04-12-13-20/ PRE dt=2009-04-12-14-00/ PRE dt=2009-04-12-14-05/ PRE dt=2009-04-12-14-10/ PRE dt=2009-04-12-14-15/ PRE dt=2009-04-12-14-20/ PRE dt=2009-04-12-15-00/ PRE dt=2009-04-12-15-05/

여기서 로그는 날짜, 시간 및 분 단위로 설정된 열 이름(dt)으로 저장됩니다. 분할된 열의 상위 폴더 위치, 스키마 및 이름을 DDL에 포함하면 Athena가 해당 하위 폴더의 데이터를 쿼리할 수 있습니다.

테이블 생성

이 데이터로 테이블을 생성하려면 다음 Athena DDL 문과 같이 'dt'를 따라 파티션을 생성합니다.

CREATE EXTERNAL TABLE impressions ( requestBeginTime string, adId string, impressionId string, referrer string, userAgent string, userCookie string, ip string, number string, processId string, browserCookie string, requestEndTime string, timers struct<modelLookup:string, requestTime:string>, threadId string, hostname string, sessionId string) PARTITIONED BY (dt string) ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;

이 테이블은 Hive의 기본 JSON serializer-deserializer를 사용하여 Amazon S3에 저장된 JSON 데이터를 읽습니다. 지원되는 형식에 대한 자세한 내용은 데이터에 적합한 SerDe 선택 단원을 참조하세요.

MSCK REPAIR TABLE 실행

CREATE TABLE 쿼리 실행 후 Athena 쿼리 편집기에서 MSCK REPAIR TABLE 명령을 실행하여 다음 예와 같이 파티션을 로드합니다.

MSCK REPAIR TABLE impressions

이 명령을 실행하면 데이터를 쿼리할 준비가 됩니다.

데이터 쿼리

파티션 열을 사용하여 노출 테이블의 데이터를 쿼리합니다. 다음은 그 예입니다.

SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100

이 쿼리는 다음과 비슷한 결과를 표시합니다.

2009-04-12-13-20 ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc 2009-04-12-13-20 17uchtodoS9kdeQP1x0XThKl5IuRsV 2009-04-12-13-20 JOUf1SCtRwviGw8sVcghqE5h0nkgtp 2009-04-12-13-20 NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH 2009-04-12-13-20 fFAItiBMsgqro9kRdIwbeX60SROaxr 2009-04-12-13-20 V4og4R9W6G3QjHHwF7gI1cSqig5D1G 2009-04-12-13-20 hPEPtBwk45msmwWTxPVVo1kVu4v11b 2009-04-12-13-20 v0SkfxegheD90gp31UCr6FplnKpx6i 2009-04-12-13-20 1iD9odVgOIi4QWkwHMcOhmwTkWDKfj 2009-04-12-13-20 b31tJiIA25CK8eDHQrHnbcknfSndUk

다음 예에서 aws s3 ls 명령은 Amazon S3에 저장된 ELB 로그를 보여줍니다. 데이터 레이아웃이 key=value 페어를 사용하지 않으므로 Hive 형식이 아니라는 점에 유의하세요. (aws s3 ls 명령에 대한 --recursive 옵션은 지정된 디렉터리 또는 접두사 아래의 모든 파일 또는 객체를 나열하도록 지정합니다.)

aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive 2016-11-23 17:54:46 11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 0 elb/plaintext/2015/01/01_$folder$ 2016-11-23 17:54:47 9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 0 elb/plaintext/2015/01/02_$folder$ 2016-11-23 17:54:48 11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 0 elb/plaintext/2015/01/03_$folder$ 2016-11-23 17:54:50 8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 0 elb/plaintext/2015/01/04_$folder$ 2016-11-23 17:54:51 7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 0 elb/plaintext/2015/01/05_$folder$ 2016-11-23 17:54:51 11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 0 elb/plaintext/2015/01/06_$folder$ 2016-11-23 17:54:52 8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 0 elb/plaintext/2015/01/07_$folder$ 2016-11-23 17:54:53 0 elb/plaintext/2015/01_$folder$ 2016-11-23 17:54:53 0 elb/plaintext/2015_$folder$

ALTER TABLE ADD PARTITION 실행

데이터가 Hive 형식이 아니므로 MSCK REPAIR TABLE 명령을 사용하여 테이블을 생성한 후 테이블에 파티션을 추가합니다. 그 대신 ALTER TABLE ADD PARTITION 명령을 사용하여 각 파티션을 수동으로 추가할 수 있습니다. 예를 들어 s3://athena-examples-myregion/elb/plaintext/2015/01/01/에 데이터를 로드하려면 다음 쿼리를 실행합니다. 각 Amazon S3 폴더에 대해 별도의 파티션 열이 필요하지 않으며, 파티션 키 값이 Amazon S3 키와 다를 수 있습니다.

ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'

파티션이 이미 있는 경우 오류(파티션이 이미 있습니다.)가 수신됩니다. 이 오류를 방지하기 위해 IF NOT EXISTS 절을 사용할 수 있습니다. 자세한 내용은 ALTER TABLE ADD PARTITION 단원을 참조하십시오. 파티션을 제거하려면 ALTER TABLE DROP PARTITION을 사용합니다.

파티션 프로젝션 고려

파티션을 직접 관리하지 않으려면 파티션 프로젝션을 사용합니다. 파티션 프로젝션은 구조가 미리 알려진 고도로 분할된 테이블에 대한 옵션입니다. 파티션 프로젝션에서 파티션 값 및 위치는 메타데이터 리포지토리에서 읽지 않고 구성하는 테이블 속성에서 계산됩니다. 인메모리 계산은 원격 조회보다 빠르기 때문에 파티션 프로젝션을 사용하면 쿼리 런타임을 크게 줄일 수 있습니다.

자세한 내용은 Amazon Athena에서 파티션 프로젝션 사용 단원을 참조하십시오.

추가 리소스