본문 바로가기
IT 정보

AWS Athena 비용 절감작업 회고

by 완기 2022. 7. 27.
728x90
반응형

최근 회사에서 AWS athena 비용 절감 작업을 진행했다.

 

기존엔 S3 수명주기 규칙을 이용하여 오래된 데이터는 자동으로 삭제되도록 자동화를 진행했지만 (참고)

다른 팀의 요청으로 부득이하게 수명주기 규칙을 일시 정지했다.

 

그러다보니, 데이터가 s3에 적재되는 양이 많아졌고,

이에 따라 아테나 스캔에 대한 비용이 증가했다. (S3에 물리적인 데이터가 삭제되지 않았기 때문에.)

 

(뭐 물론 한 번에 하려고 서브 쿼리를 넣은 등, 쿼리 최적화 누락에 대한 문제도 있었다...)

 

기존에 방식은 JSON 형태의 데이터를 일정 크기에 맞게 압축해서 파티셔닝 했다.

이 방법도 AWS 공식 문서에서 소개하는 최적화 방법이긴 하다.

 

그러나 물리적인 데이터 양이 많아져서 다른 방법이 필요했다.

 

회사 팀장님께서 'Parquet(이하 파케이) 형태로 데이터를 적재하면 어떨까'라고 해서 관련 자료를 찾아보기 시작했다.

 

 

Parquet (파케이)

이번 글은 하둡 생태계에서 많이 사용되는 파일 포맷인 Parquet (이하 파케이)에 대해 정리한다. 글의 포함된 설명 중 많은 부분은 하둡 완벽 가이드에서 발췌한 것임을 밝힌다. 파케이는 columnar 저

devidea.tistory.com

 

 

파케이 관련 자료는 이해하기 쉬운 블로그 글이 있어 참고하면 좋다.

파케이는 빅데이터 생태계에서 많이 사용된다고 한다.

 

컬럼 기반의 자료형으로 컬럼 단위의 구성으로 압축률이 좋고,

데이터를 가져갈 때, 컬럼을 선택해서 가져가게 되면 칼럼 단위로 저장된 파케이는 선택된 데이터만 가져가기 때문에 I/O가 많이 줄어든다.

 

압축률이 좋다는 건 더 적은 데이터를 의미하고 곧 아테나의 스캔 비용 절감을 의미한다.

 

AWS Athena의 과금 기준

 

 

Amazon Athena 요금 - 서버리스 대화식 쿼리 서비스 - Amazon Web Services

크기가 같은 3개의 컬럼으로 구성된 테이블이 있고, 총 3TB의 압축되지 않은 텍스트 파일이 Amazon S3에 저장되어 있다고 가정해 보겠습니다. 이 테이블의 한 컬럼에서 데이터를 가져오도록 쿼리를

aws.amazon.com

 

 

일단 파케이를 사용하기로 결정했고,

나의 상황은 원본 데이터는 삭제, 수정이 일어나지 않은 상태에서 Copy Table을 해야 했다.(안전상의 이유...)

 

다행이게도 AWS 공식 문서에 파케이 형태로 마이그레이션을 할 때 참고할 문서가 존재했다.

바로 CTAS를 이용하는 것이다.

 

ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용 - Amazon Athena

ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용 Athena에서 Create Table as Select(CTAS) 및 INSERT INTO 문을 사용하면 데이터 처리를 위해 Amazon S3에 데이터를 추출, 변환 및 로드(ETL)할 수 있습니다. 이 주제에서

docs.aws.amazon.com

 

약자로 되어있어 어려워 보이지만 CTAS는 Copy Table as Select다.

 

SQL에서 Insert as select와 같다. (참고)

 

CREATE table {schema}."{table_name}" WITH (
	format = 'PARQUET',
	parquet_compression = 'SNAPPY',
	partitioned_by = array [{파티션할 컬럼 배열}], # ex) ['a','b','c']
	external_location = '{S3 경로}' # ex)s3://{버킷}/{경로}/{경로2}
) AS
SELECT {넣을 컬럼들}
FROM {스키마}.{데이터를 복사할 원본 테이블}
WHERE {파티션 조건};

실제 사용했던 CTAS문을 첨부한다.

 

다만 여기서 유의 사항이 있다.

  • partitioned_by에서 선언된 배열에 순서에 맞게 SELECT 절 마지막에 넣어줘야 한다.
    • ex) 파티션이 ['a', 'b', 'c'] 일 경우, SELECT {...컬럼들}, a, b , c. (O)
    • ex) SELECT {...컬럼들}, b, c , a. (X) -> 에러 발생.
  • SELECT 절에서 파티션에 따라 조건절을 넣어줘야 한다. (풀스캔을 하게 되면 돈이 많이 나온다...)
  • CTAS문에서는 최대 100개 이상의 파티션의 데이터가 생성되면 에러를 발생시킨다.
    • 이 경우, 데이터를 옮기는 범위를 조금 줄여서 여러 번 실행해야 한다.

 

 

이렇게 해서 데이터를 다 옮기고 나면 눈에 띄는 성능 차이를 경험할 수 있다.

 

변경 전 (JSON형태의 데이터 압축)

 

약 8.19GB의 데이터를 스캔하는데 약 15초가 소요됐다.

 

변경 후 (파케이로 변경)

같은 쿼리에서 테이블만 바꿨는데, 기존에는 8.19GB를 스캔하던 쿼리가 693.74KB를 스캔하도록 성능이 향상됐다.

시간도 15초에서 약 3초로 백분율로 따지면 시간은 약 79% , 스캔 데이터 양은 99% 감소했다.

 

아직 바꾼 지 얼마 안 됐지만 추가적인 이슈 사항이 생기면 내용을 추가해야겠다.

 

728x90
728x90

댓글