본문 바로가기
Troubleshooting/AWS

[AWS Athena] S3 Parquet 파티션 빅데이터 쿼리 엔진 설정 (테이블/파티션 인식 불가 트러블 슈팅)

by 코딩하는 동현 2025. 11. 9.

1. 개요: 전체 파이프라인 흐름과 현재 위치

이 아키텍처는 공공데이터 API의 대용량 데이터를 '최소 비용'으로 분석하는 것을 목표로 한다. 이 목표를 달성하기 위해 데이터는 다음과 같은 파이프라인을 거친다.

  1. [API → Lambda] : OutOfMemory 문제를 피하기 위해 Lambda가 API를 스트리밍으로 호출한다.
  2. [Lambda → S3 RAW] : Lambda는 데이터를 메모리에 쌓아두지 않고, part_N.json 형태의 작은 파일로 분할하여 S3 RAW 버킷에 즉시 적재한다.
  3. [S3 RAW → Glue] : Glue (PySpark) Job이 S3 RAW의 분할 JSON '폴더'를 통째로 읽어 9가지 전처리 로직을 적용한다.
  4. [Glue → S3 Processed] : Glue는 처리된 데이터를 Parquet(컬럼 기반) 포맷으로 변환하고, .../district=gwangjin/ 처럼 파티셔닝하여 S3 Processed 버킷에 저장한다.

현재 데이터는 S3 Processed 버킷에 분석에 최적화된 상태로 저장되어 있다. 이 글은 이 데이터를 쿼리하기 위한 최종 엔진, Amazon Athena를 설정하는 과정에서 발생하는 3가지 주요 문제와 그 개념적 원인을 다룬다.


2. 문제 1: 쿼리 실행 불가 ("Query result location...")

  • 현상: Athena 쿼리 편집기에 처음 접속하자마자, 쿼리 실행 자체가 불가능하며 "Before you run your first query, you need to set up a query result location in Amazon S3."라는 파란색 경고가 발생한다.
  • 원인: Athena는 데이터를 저장하지 않는 '서버리스 쿼리 엔진'이다. 따라서 SELECT 문의 결과(주로 CSV 파일)를 저장할 별도의 S3 버킷이 반드시 필요하다. 엔진은 있으나 결과물을 둘 곳이 없는 상태이다.
  • 해결: Edit settings를 클릭하여, 미리 생성해 둔 쿼리 결과 전용 S3 버킷 (예: s3://food-donor-athena-results-v1/) 경로를 지정하고 저장한다.


3. 문제 2: 테이블을 찾을 수 없음 (S3 데이터 인식 불가)

  • 현상: 쿼리 결과 버킷을 설정했음에도, SELECT * FROM food_donor_db.restaurants ... 쿼리 실행 시 Table not found 오류가 발생한다. S3 Processed 버킷에 Parquet 파일이 존재하는데도 Athena는 '테이블'을 인식하지 못한다.
  • 개념: 분리된 스토리지(S3)와 메타데이터(Glue Catalog) 이 문제가 발생하는 이유는 Athena 아키텍처의 핵심 개념인 '스토리지와 컴퓨팅의 분리' 때문이다.
    1. S3 (스토리지): '데이터 창고'이다. S3는 파일(part-....parquet)과 폴더(district=...)를 바이트 덩어리로 저장할 뿐, 이 파일이 'restaurants' 테이블의 일부인지, id 컬럼이 STRING 타입인지 전혀 알지 못한다.
    2. Athena (컴퓨팅): '쿼리 엔진'이다. SQL을 실행하지만, 자체적으로 데이터를 저장하지 않는다.
    3. AWS Glue Data Catalog (메타데이터): S3와 Athena를 연결하는 **'마스터 장부' 또는 '설계도'**이다. 이 카탈로그에는 " food_donor_db.restaurants라는 테이블이 존재하고, 그 스키마는 id STRING, ...이며, 실제 데이터는 s3://.../에 Parquet 형식으로 저장되어 있다"라는 **정보(메타데이터)**가 기록된다.
  • 원인: Table not found 오류는 Athena가 S3를 뒤지기 전에, 먼저 '마스터 장부(Glue Catalog)'를 확인했으나 restaurants라는 항목 자체가 등록되어 있지 않기 때문에 발생한다.
  • 해결: CREATE EXTERNAL TABLE 쿼리를 실행하여, 이 '마스터 장부(Glue Catalog)'에 수동으로 설계도를 등록한다.
-- 1. 캐비닛(데이터베이스) 생성
CREATE DATABASE IF NOT EXISTS food_donor_db;

-- 2. 장부(테이블) 등록
CREATE EXTERNAL TABLE food_donor_db.restaurants (
    id STRING,
    name STRING,
    post_number STRING,
    address STRING,
    phone_number STRING,
    longitude STRING,
    latitude STRING,
    type STRING
)
-- [개념] 이 데이터가 파티션 폴더로 나뉘어 있음을 '장부'에 기록
PARTITIONED BY (
    partition_date STRING,
    district STRING
)
-- [개념] 이 데이터가 Parquet 형식임을 '장부'에 기록
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
-- [개념] 데이터의 S3 창고 위치를 '장부'에 기록
LOCATION 's3://food-donor-processed-data-v1/'
TBLPROPERTIES ('classification'='parquet');

 

이 쿼리는 데이터를 복사하거나 생성하는 것이 아니라, 오직 Glue Data Catalog에 메타데이터 항목을 생성하는 작업이다.

 


4. 문제 3: 신규 데이터(파티션)가 조회되지 않음

  • 현상: CREATE TABLE까지 성공했다. 하지만 어제 Lambda/Glue 파이프라인이 새로 실행되어 S3에 partition_date=2025-11-09 폴더가 생성되었음에도, Athena에서 SELECT 해도 해당 날짜의 데이터가 조회되지 않는다.
  • 원인: '마스터 장부(Glue Catalog)'는 정적(Static)이다. S3(창고)에 새 폴더(선반)가 생겼다고 해서, '장부'가 자동으로 갱신되지 않는다. CREATE TABLE 시점에 존재했던 파티션 목록만 등록되어 있을 뿐이다.
  • 해결: MSCK REPAIR TABLE 명령어를 실행하여, S3 LOCATION을 강제로 다시 스캔하고, '장부(메타데이터)'를 최신 S3 상태로 갱신(Repair)한다.
MSCK REPAIR TABLE food_donor_db.restaurants;
  • 운영 개념: 이 명령어는 파이프라인이 실행되어 새로운 파티션(폴더)이 추가될 때마다 (이 아키텍처에서는 매일 또는 매월) 반드시 1회 실행되어야 한다. (이 작업은 추후 Lambda로 자동화할 수 있다.)


Athena의 S3 버킷에 Glue Data Catalog에 메타데이터 항목을 생성된 모습


5. 결론 및 배운 점

  • [문제 1 해결] Athena는 '엔진'일 뿐이므로, SELECT 결과(CSV)를 저장할 별도의 S3 버킷을 최초 1회 설정해야 한다.
  • [문제 2 해결] S3(스토리지)Athena(컴퓨팅)Glue Data Catalog(메타데이터)를 통해 연결된다. CREATE EXTERNAL TABLE은 S3 파일을 스캔하는 것이 아니라, 이 카탈로그에 '설계도'를 등록하는 작업이다.
  • [비용 최적화] CREATE TABLE 시점에 PARTITIONED BY (파티션 프루닝)와 TBLPROPERTIES ('parquet') (컬럼 기반 스캔)를 반드시 명시해야 '최소 비용' 쿼리가 가능하다.
  • [문제 3 해결] 카탈로그는 정적이다. S3에 신규 파티션(폴더)이 추가되어도 Athena는 자동으로 인식하지 못한다. MSCK REPAIR TABLE을 주기적으로 실행하여 메타데이터를 갱신해야 하는 이유이다.
반응형

댓글