본문 바로가기
Amazon AWS/S3

AWS Athena를 사용해서 S3의 데이터에 쿼리 쓰기

by 홍띠 2022. 11. 20.

S3에 저장되어 있는 데이터들을 조회할 때, AWS의 Athena 서비스를 이용하면 S3의 파일들을 다운받거나 불러오지 않더라도 표준 SQL을 사용해서 쿼리로 편하게 데이터를 조회할 수 있다.

Amazon Athena란 무엇인가요? (AWS 문서 설명: https://docs.aws.amazon.com/ko_kr/athena/latest/ug/what-is.html)
Amazon Athena는 표준 SQL을 사용하여 Amazon S3(Amazon Simple Storage Service)에 있는 데이터를 직접 간편하게 분석할 수 있는 대화형 쿼리 서비스입니다. AWS Management Console에서 몇 가지 작업을 수행하면 Athena에서 Amazon S3에 저장된 데이터를 지정하고 표준 SQL을 사용하여 임시 쿼리를 실행하여 몇 초 안에 결과를 얻을 수 있습니다.
Athena는 서버리스 서비스이므로 설정하거나 관리할 인프라가 없으며 실행한 쿼리에 대해서만 비용을 지불하면 됩니다. Athena는 자동으로 확장되어 쿼리를 병렬로 실행하여 대규모 데이터 집합과 복잡한 쿼리에서도 빠르게 결과를 얻을 수 있습니다.

다만, 경험상 파티셔닝을 사용하고, parquet 형식의 파일을 사용하더라도, 쿼리속도가 빠르지는 않다보니 빠른 처리속도를 요구하는 작업에는 적합하지 않은 듯 하다. 관련해서 다른 대안이나 방법이 있는지는 좀 더 공부가 필요하다.


💡 S3 버킷은 기존에 사용하던 버킷을 사용하므로, 버킷 생성에 대한 설명은 아래에서 설명하지 않으므로 공식문서를 참고하면 된다.
(공식 문서: https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/create-bucket-overview.html)

이번에 조회할 데이터는 S3에 저장되어 있는 json 형식의 로그 파일이다. 데이터는 연,월,일 로 디렉토리가 분류되어 저장되어 있다.

 

1. Athena 콘솔의 쿼리 에디터에 접속

AWS 콘솔에서 Atheana 접속 후 쿼리에디터에 들어간다.

쿼리에디터에 처음 진입한다면, 위의 사진 처럼 쿼리를 시작하기 전에 query result 위치를 지정하라는 안내가 나온다.

2. 쿼리 결과 위치(S3 버킷) 설정

안내문의 Edit Settings를 클릭하거나, 상단 메뉴에서 Settings에 들어가면 Query result location을 설정 할 수 있다.

내경우에는 조회대상 버킷과 따로 관리하는것이 나을것이라 생각되어 result용 버킷을 따로 만들어서 지정해 주었다.

3. 데이터베이스 생성

Athena의 데이터베이스는 사용자가 작성한 테이블에 대한 논리적인 그룹이다. 

콘솔의 쿼리에디터에서 아래의 명령어를 실행시킨다.

CREATE DATABASE sample_database;

입력 창 아래 Run을 실행시켜도 되고,  Ctrl+Enter를 눌러 실행 시켜도 된다.

4. 테이블 생성

아래 명령어를 실행해서  테이블을 생성한다.

여기서 테이블의 컬럼을 지정하고, 읽어 올 데이터의 포맷에 맞춰서  SerDe 라이브러리를 지정한다. 여기서는 json형식의 데이터를 읽어오기 때문에, json 포맷에 맞게 지정하였다. 또한, 조회 대상 버킷의 루트 경로도 지정해준다.

그리고, 파티션 열을 정의해준다. 파티션 열은 데이터가 분할되어 저장되어 있는 경로에 맞추어 지정해 주면 된다. 이번 경우에는 S3의 데이터 경로가 ~/year/month/day/~~.json 의 경로로 이루어져 있으므로 연/월/일를 파티션 열로 지정했다.

SerDe 란?(공식문서: https://docs.aws.amazon.com/ko_kr/athena/latest/ug/serde-about.html)
SerDe(Serializer/Deserializer)는 Athena가 다양한 형식의 데이터와 상호 작용하는 한 방식입니다.
테이블 스키마는 DDL이 아니라 개발자가 지정한 SerDe에 의해 정의됩니다. 즉, SerDe는 Athena에서 테이블을 생성할 때 지정한 DDL 구성을 재정의할 수 있습니다.
CREATE EXTERNAL TABLE IF NOT EXISTS web_log (
    `timestamp` STRING,
    log STRING,
    node STRING,
    pod_name STRING,
    pod_ip STRING
) PARTITIONED BY (
    year int,
    month int,
    day int
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://log-bucket/web-log/';

5. 파티션 등록 및 추가

위의 테이블 생성에서 잠시 언급 되었지만, Athena를 이용해 S3의 데이터를 조회 할때는 파티션을 적절하게 사용해야 한다. 파티션을 사용하지 않으면 쿼리가 S3 전체의 데이터를 조회해야 하기 때문에 쿼리 속도의 저하도 일으키고 비용도 불필요하게 많이 발생하게 된다.

Athena에서 파티션을 등록하는 방법은 여러가지가 있다.
대표적으로는 Glue의 크롤러를 이용하면, 크롤러가 자동으로 파티션을 인식해서 등록해 주기 때문에 좀 더 효율적으로 이용 할 수 있다. 다만, 크롤러는 또 추가적인 비용이 발생하므로 상황에 맞게 이용하면 된다.
두번째는 Athena에서 쿼리를 사용해서 등록해 주는 것이다.
Hive 스타일 형식(e.g. S3://sample/path/year=2022/month=11/ )에 맞게 데이터가 저장되어 있다면 좀 더 간편하게 자동으로 파티셔닝을 등록하도록 쿼리를 수행 할 수 있다. 하지만 자동 파티셔닝은 매번 모든 파티션을 등록하므로 파티션 개수가 많아지면 성능의 저하가 일어난다.
Hive 스타일의 경로가 아니거나, 자동 파티셔닝을 이용하지 않는다면 수동으로 파티션을 등록해 주는 방법도 있다. 파티션이 생성 될 때마다 매번 새로 등록해 주어야 한다는 단점이 있지만, 데이터를 일시적으로 조회하고자 하는 경우에는 추가적인 비용없이 사용 할 수 있는 방법이다.

이번에는 아테나의 쿼리를 이용해서 수동으로 파티션을 등록해서 사용해본다. 나중에 Glue 크롤러를 사용해서 테이블을 추가하는것도 따로 게시글을 올리려고 한다.

 

파티션 등록은 아래의 명령어를 실행해서 등록해준다.

ALTER TABLE web_log
ADD PARTITION (year='2022',month='10',day='04')
LOCATION 's3://log-bucket/web-log/2022/10/04/';

아래 show 명령어를 사용해서 등록된 파티션을 조회해 볼 수도 있다. 결과를 확인해보면 정상적으로 등록된 것을 확인 할 수 있다.

6. 쿼리 실행

이제, 설정한 파티션을 where 조건에 포함해서 쿼리를 실행하면 된다. 아래는 select문 예시이다.

위의 화면과 같이 정상적으로 쿼리가 실행되어 데이터가 조회되는것을 확인 할 수 있다.

 

참고:
https://docs.aws.amazon.com/ko_kr/athena/latest/ug/getting-started.html

https://aws.amazon.com/ko/premiumsupport/knowledge-center/athena-create-use-partitioned-tables/