개발자를 위한 데이터 도구 환경 가이드
출처: OlegWock (sinja.io)
원문: https://sinja.io/blog/data-landscape-guide-for-developers
작성자: 팔복소프트-김팔복
한눈에 보기
- 데이터 전문가가 되려는 사람이 아니라, 데이터 팀 회의에서 무슨 말인지 알아듣고 싶은 개발자를 대상으로 데이터 생애주기 전체를 훑는 안내서다.
- 웨어하우스·레이크·레이크하우스의 차이를 "제품 비교"가 아니라 저장·메타데이터·쿼리 엔진이 결합되어 있느냐 분리되어 있느냐의 구조 차이로 설명한다.
- 수집 → 처리(SQL/데이터프레임/분산/스트림) → 적재(메달리온, 차원 모델링) → 소비(BI, 운영 분석, 노트북)까지 각 단계에 어떤 도구가 왜 존재하는지 매핑해준다.
- 오케스트레이터는 배치 전용이고 스트리밍에는 맞지 않는다는 식의, 카테고리 경계에 대한 설명이 특히 유용하다.
- 저자는 도구 설치법이나 동일 카테고리 내 심층 비교는 다루지 않는다고 명시했다. 지형 파악용 지도로 봐야 한다.
주요 내용
이 글이 나온 배경
저자는 데이터 경험 없이 소프트웨어 엔지니어로 Deepnote(데이터 팀용 클라우드 노트북)에 합류했다. 노트북이 뭔지는 알았지만, 노트북 밖의 수많은 데이터 도구가 무엇에 쓰이고 서로 어떻게 맞물리는지는 전혀 몰랐다고 한다. 그 상태로는 노트북에 어떤 기능이 필요한지 제안할 수도, 어떤 UI 흐름이 문제인지 짚어낼 수도 없었다는 것이다.
기사와 문서를 뒤지고 동료와 고객의 작업 흐름을 관찰하며 얻은 지식을, "데이터 회사에 떨어졌는데 다들 무슨 말을 하는지 모르겠는 개발자"용으로 정리한 결과물이다. 그래서 대시보드 만드는 법이나 통계 기초, Spark 클러스터 운영은 다루지 않는다.
데이터 직군은 크게 네 가지
용어가 안 들리는 첫 번째 이유는 상대가 누구인지 모르기 때문이다. 저자는 경계가 흐릿하다는 전제를 달고 네 유형으로 나눈다.
- 분석형(data analyst, BI analyst) — 데이터를 해석하고 인사이트를 뽑아 전달한다. SQL과 스프레드시트에 능하고 Tableau 같은 BI 도구를 쓴다. 지역별 이탈률을 뽑아 대시보드를 만들고 마케팅팀에 리텐션 캠페인을 제안하는 식이다.
- 과학형(data scientist) — 표면적 리포팅보다 깊게 들어간다. 통계를 적용하고 모델을 만들고 실험을 설계한다. Python 과학 스택(pandas, scikit-learn)과 노트북이 주 무대다. 어떤 요인이 이탈과 상관관계가 있는지 찾고, A/B 테스트를 설계해 효과를 검증한다.
- 엔지니어링형(data engineer) — 데이터를 분석 가능한 상태로 만드는 인프라 담당이다. 파이프라인을 만들고 스키마를 표준화해 웨어하우스나 레이크에 적재한다. 분석가가 만든 일회성 분석을 안정적으로 반복 실행되는 파이프라인으로 확장하는 것도 이쪽 일이다.
- 머신러닝형 — 모델을 만들고 운영한다. 앞의 유형들과 겹쳐 보이지만 도구 세트가 상당히 다르다. 저자는 이 영역은 지식이 제한적이라며 깊게 다루지 않는다고 밝혔다.
ETL과 ELT
기본 흐름은 ETL이다. 소스에서 원본을 추출하고(Extract), 정제·결합 등으로 변환하고(Transform), 최종 목적지에 적재한다(Load).
다만 순서가 고정된 규칙은 아니다. 널리 쓰이는 대안인 ELT는 추출한 데이터를 웨어하우스에 바로 넣고 그 안에서 변환한 뒤 결과를 다른 테이블에 저장한다. 저장과 연산이 추가되니 비용은 올라간다. 대신 원본이 남아서 나중에 다른 방식으로 처리해야 할 상황이 생겼을 때 대응할 수 있다.
데이터는 어떻게 저장되는가
파일 포맷. CSV는 적은 양을 옮기기 편하고 사무용 소프트웨어로 열 수 있어서 비기술 사용자에게 좋다. Parquet는 기술 사용자 쪽이다. 열 단위로 배치하는 컬럼 포맷이라 압축이 잘 되고, 대부분의 데이터 도구가 읽고 쓸 수 있어서 저자는 데이터 도구계의 링구아 프랑카라고 표현한다. 비슷한 문제를 푸는 Apache ORC, 그리고 행 지향 바이너리 포맷으로 레코드 전달과 스트리밍에 쓰이는 Apache Avro도 언급된다.
메모리 포맷. 파일뿐 아니라 메모리에 올라간 데이터에도 포맷이 있다. 사실상 표준은 Apache Arrow다. Parquet가 압축과 파일 크기에 최적화된 저장·전송용이라면, Arrow는 처리와 제로 카피 전송에 최적화되어 있다. 공간은 더 먹지만 도구 간 이동이 아주 효율적이다. Python의 pandas에서 Rust의 DataFusion으로 넘길 때처럼. pandas는 Arrow를 선택적 백엔드로 쓸 수 있고, Polars나 DataFusion은 처음부터 Arrow 위에 세워진 프로젝트다.
웨어하우스 · 레이크 · 레이크하우스
데이터 웨어하우스는 PostgreSQL·MySQL 같은 데이터베이스와 비슷하지만 분석 부하에 최적화되어 있다. MySQL은 행 단위로 최적화된 OLTP라 "id로 사용자 한 행 가져오기"에 강하고, 웨어하우스는 열 단위로 최적화된 OLAP라 "작년 지역별 총매출" 같은 집계에 훨씬 빠르다.
여기서 개발자가 놓치기 쉬운 지점이 있다. 웨어하우스는 데이터를 디스크에 어떻게 저장할지와 어떻게 질의할지를 모두 직접 관리하고, 자체 쿼리 엔진과 강하게 묶여 있다. MySQL이나 Mongo만 써온 사람에겐 당연하게 들리겠지만, 다른 저장 방식에서는 그렇지 않다는 게 뒤에 나올 핵심이다. 세 가지 중 가장 비싼데, 성능과 편의성을 함께 사는 값이다.
데이터 레이크는 정반대다. CSV, Parquet, JSON을 처리 없이 그냥 쏟아붓는 곳이다. 저자의 표현으로는 "부가 기능이 좀 붙은 커다란 클라우드 폴더"에 가깝다. 구조에 제약이 없어서 구조화(Parquet), 반구조화(CSV), 비구조화(이메일), 바이너리(이미지)를 다 담을 수 있다. S3·GCS·Azure Blob 같은 저렴한 스토리지에 네이밍과 파티셔닝 규칙을 정하고 접근 정책을 세운 뒤, 메타데이터 카탈로그와 쿼리 엔진을 붙이면 레이크가 된다. 관리를 안 하면 데이터 늪(data swamp)이 된다는 경고도 붙어 있다.
이 두 구성 요소가 왜 필요한가. 쿼리 엔진은 SQL을 받아 레이크의 데이터에 실행한다. 그러려면 어떤 테이블이 있고 스키마가 무엇이며 어떤 파일에 매핑되는지 알아야 하는데, 그걸 알려주는 게 메타데이터 카탈로그다. 덕분에 스크립트에서 CSV 파일을 직접 찾아 다운로드하고 파싱하는 대신 그냥 쿼리를 던질 수 있다.
데이터 레이크하우스는 이름 그대로 둘을 합친 것이다. 레이크 위에 블록을 몇 개 얹어 웨어하우스에 가깝게 만든다. 가장 중요한 블록이 테이블 포맷으로, 쿼리 엔진과 원본 데이터 사이에서 저장 방식을 관리한다. 여기서 얻는 것들:
- ACID — 여러 애플리케이션이 동시에 작업해도 데이터가 깨지지 않는다. 동시 쓰기와 쓰기 도중 오류를 레이크하우스가 처리한다.
- 스키마 강제와 진화 — 레이크보다 엄격하다. 반구조화 데이터도 담을 수 있지만 구조를 정의해야 하고 레이크하우스가 그걸 강제한다. 완전한 비구조화 데이터는 대상이 아니다. 스키마 변경 이력도 추적한다.
- 성능 — 데이터와 스키마를 통제하니 인덱스를 만들고 파티셔닝을 최적화할 수 있다.
- 타임 트래블 — 특정 시점 스냅샷에 쿼리를 실행할 수 있는 경우도 있다.
비용은 저렴한 스토리지 위에 얹히므로 웨어하우스보다 싸다. 다만 레이크하우스는 웨어하우스와 달리 특정 쿼리 엔진에 묶이지 않아서 일대일 비교는 어렵다는 단서가 붙는다. 작업 성격에 따라 레이크하우스 + 컴퓨트 조합이 웨어하우스보다 훨씬 저렴할 수 있다.
수집과 CDC
데이터는 어디서든 온다. PostgreSQL·Mongo 같은 자체 DB, Stripe 같은 서드파티 API, 사용자 브라우저가 보내는 분석 이벤트, IoT 기기.
직접 스크립트를 짤 수도 있지만, 저자의 지적처럼 "Stripe 데이터를 BigQuery에 넣는 Python 스크립트가 세상에 몇 개나 있을까"를 생각하면 대부분은 이미 수백 번 쓰인 코드다. 수집 도구를 쓰면 인증·페이지네이션·에러 처리 같은 접착 코드 대신 소스와 목적지 커넥터를 설정하는 것으로 끝난다. 다만 이 접근은 자연스럽게 ELT 쪽으로 밀어붙인다. 추출한 데이터가 어딘가 먼저 착지해야 하기 때문이다.
DB에서 가져올 때는 **CDC(change data capture)**를 만나게 된다. 새 데이터를 찾으려고 테이블을 반복 조회하는 대신, DB의 복제 로그를 읽어 INSERT·UPDATE·DELETE를 발생 시점에 잡아내는 방식이다. 수집 도구들이 내부적으로 이걸 쓰고, 독립 구성 요소로 필요하면 Debezium이 널리 쓰인다.
처리 방식 네 가지
SQL 기반 변환. 쿼리 엔진에게 일을 시키는 방식이다. dbt와 SQLMesh가 대표적인데, 변환을 SELECT 문으로 기술하면 도구가 이를 컴파일해 엔진이 실행하게 한다. dbt와 SQLMesh 자체는 데이터를 직접 다루지 않는다. 장점은 표준화 외에도 복잡한 변환을 의존성 있는 작은 조각으로 쪼갤 수 있다는 점이다. dbt는 테이블 이름을 하드코딩하는 대신 모델을 참조(ref)하게 하고, 의존성 그래프를 만들어 올바른 순서로 처리한다.
로컬 데이터프레임. 2차원 배열 위의 추상화로 표 형태 데이터를 다룬다. pandas가 사실상 표준이고, Polars, Rust의 DataFusion, Julia의 DataFrames.jl 등이 있다. 여기서 구분해둘 개념이 eager와 lazy다. pandas는 eager라 groupby().sum()을 호출하면 즉시 실행한다. Polars의 LazyFrame이나 DataFusion은 lazy라 연산을 논리 계획으로만 쌓아두고 .collect()를 호출할 때 실행한다. 실행 전에 계획을 최적화할 여지가 생긴다.
공통 한계는 데이터가 내 머신에 있고 로컬에서 처리된다는 점이다. pandas는 전부 메모리에 올리므로 RAM에 묶인다. Polars처럼 스트림 처리를 지원해 RAM보다 큰 데이터를 다루는 경우도 있지만 만능은 아니고, CPU 제약은 여전하다.
로컬 이야기에서 DuckDB가 별도로 언급된다. "분석용 SQLite"라 불리는 인프로세스 OLAP 데이터베이스로, 인프라 세팅 없이 CSV·Parquet 파일과 심지어 pandas DataFrame까지 SQL로 질의할 수 있다.
분산 처리. 한 대로 감당이 안 되면 여러 대에 나눈다. Hadoop이 원조지만 지금은 레거시 취급이고, 사실상 표준은 Apache Spark다. Spark가 로딩과 변환, 병렬화와 최적화를 맡고 사용자는 무엇을 할지 지시하는 스크립트를 쓴다. Spark는 앞서 다룬 모든 저장소를 읽고 쓸 수 있어서, 레이크의 쿼리 엔진으로도 무거운 변환의 작업마로도 쓰인다. 이 밖에 pandas/numpy API에 가깝게 클러스터로 확장하는 Dask, ML 학습에 많이 쓰이는 범용 분산 프레임워크 Ray가 있다.
스트림 처리. 결과가 급할 때(카드 부정거래 탐지) 또는 자원 효율이나 데이터 성격상 맞을 때 쓴다. 여기서 자주 등장하는 Apache Kafka는 프로듀서로부터 이벤트를 받아 저장하고 컨슈머가 읽게 해준다. 메시지 큐와의 결정적 차이는 컨슈머가 확인 응답을 해도 이벤트가 사라지지 않는다는 점이다. 로그에 남아 있어서 다른 컨슈머가, 혹은 같은 컨슈머가 보관 정책에 따라 만료될 때까지 몇 번이고 다시 읽을 수 있다.
중요한 건 Kafka 자체는 처리를 하지 않는다는 것이다. 처리는 별도 워커가 하고, Kafka 입장에서 그건 그냥 또 하나의 컨슈머다. 그 워커 역할을 전문적으로 하는 게 Apache Flink다. 필터링, 필드 매핑, 윈도우 집계, 중복 제거, 결과 기록을 정의해서 넘기면 Flink가 클러스터에 배포하고 계속 실행한다. 이름이 비슷해 헷갈리는 Kafka Connect(외부 시스템 연결)와 Kafka Streams(앱에 임베드되는 Java/Scala 스트림 처리 라이브러리)도 구분해두면 좋다.
오케스트레이션과 모니터링
dbt 변환, Spark 잡, 커스텀 스크립트가 뒤섞여 늘어나면 전체 파악이 어려워진다. 오케스트레이터는 각 태스크가 무슨 일을 하고 무엇에 의존하는지 정의하면 DAG를 만들어준다. 정의는 대부분 코드(주로 Python)로 한다. 오케스트레이터 자체는 데이터를 처리하지 않고 Spark 스크립트 실행, dbt 변환 트리거, HTTP 엔드포인트 호출 같은 방식으로 실제 작업을 위임한다. 스케줄, Kafka 이벤트, UI 수동 실행, HTTP 요청 등으로 트리거할 수 있고, 독립적인 태스크는 병렬 실행하거나 실패한 지점부터 재개할 수 있다.
여기서 개발자가 꼭 알아둘 경계가 하나 있다. 오케스트레이터는 배치용이다. 파이프라인을 처음부터 끝까지 돌리고 다음 트리거까지 멈추는 모델이라, 끝나지 않고 계속 도는 스트림 처리에는 맞지 않는다. 스트리밍 구성에서는 Flink 같은 스트림 프로세서 자체에 의존하게 된다.
모니터링은 두 갈래다. 파이프라인 모니터링(잡이 돌았는지, 실패했는지, 얼마나 걸렸는지)은 일반 웹 앱과 스택이 비슷해서 Prometheus, Grafana, ELK가 그대로 쓰이고 오케스트레이터가 일부를 커버하기도 한다. 데이터 자체 모니터링(최신인지, 볼륨에 이상이 없는지, 스키마가 조용히 바뀌지 않았는지)은 별개 문제다. 기대하는 형태를 직접 정의하는 Great Expectations나 dbt 테스트 같은 수동 방식이 있고, 데이터를 학습해 이상을 자동으로 감지하는 Monte Carlo, Bigeye, Metaplane 같은 제품도 있다.
데이터가 착지하는 곳
착지하는 저장소는 앞서 다룬 웨어하우스·레이크·레이크하우스 그대로다. 짚어둘 점은 데이터가 마지막에 한 번만 착지하는 게 아니라 여러 단계에서 서로 다른 모습으로 여러 번 착지한다는 것이다.
메달리온 아키텍처가 이걸 정리하는 대표적 방식이다.
- Bronze — 소스에서 그대로 온 원본
- Silver — 정제하고 형태를 맞춘 것. 타입 교정, 중복 제거, 여러 소스 결합
- Gold — 집계하고 모델링해서 대시보드나 리포트 같은 특정 용도에 맞춘 것
같은 저장 시스템 안에 있지만 생애 단계가 다르다. 분석가는 보통 Gold를 조회하고, 파이프라인을 디버깅하는 엔지니어는 Bronze까지 파고든다.
차원 모델링은 정제 수준이 아니라 형태에 대한 이야기다. 분석가들이 "팩트 테이블"이나 "grain"을 언급한다면 이 어휘다. Ralph Kimball이 대중화한 접근으로, 테이블을 두 종류로 나눈다. 팩트 테이블은 사건과 측정값을 담는다. 주문 한 건, 결제 한 건, 페이지뷰 한 건이 한 행이다. 길고 좁으며 대부분 숫자와 외래 키로 이뤄지고 계속 커진다. 디멘션 테이블은 그 사건의 맥락을 담는다. 고객 한 명, 상품 하나, 날짜 하루가 한 행이다. 넓고 변화가 적다. 팩트를 가운데 두고 디멘션을 둘러 그리면 스타 스키마가 된다. (더 정규화된 변형인 스노우플레이크 스키마도 있는데, 웨어하우스 Snowflake와는 무관하다.)
grain은 한 행이 무엇을 나타내는지다. 주문 하나인지, 주문 항목 하나인지, 고객별 일자별 주문인지. 데이터 마트는 한 팀이나 주제에 맞춰 모델링한 웨어하우스의 일부로 보통 Gold 계층에 산다. 다만 저자는 모든 팀이 이걸 엄격히 따르지는 않는다고 덧붙인다. 요즘 웨어하우스가 빠르고 스토리지가 싸다 보니 용도별로 넓은 비정규화 테이블 하나를 만드는 방식(OBT, one big table)도 흔하다.
앱에 서빙할 때는 이야기가 달라진다. 내부 대시보드는 웨어하우스로 충분하지만, 많은 사용자가 동시에 밀리초 단위 응답을 요구하는 경우 — 사용자 대상 분석 기능, 실시간 모니터링, 리더보드나 사용량 미터 같은 무거운 집계 기반 기능 — 웨어하우스의 지연과 쿼리당 비용이 감당이 안 된다. 이때는 Apache Druid나 Apache Pinot 같은 실시간 OLAP 데이터베이스에 적재한다. ClickHouse도 이 용도로 아주 인기 있는 선택이다.
리버스 ETL은 방향이 반대다. Stripe에서 데이터를 끌어와 고객 생애가치를 계산한 뒤 HubSpot에 올려서 영업팀이 고가치 고객을 바로 보게 하는 식이다. 전용 도구를 쓰면 실패·재시도, 레이트 리밋, 알림, 증분 동기화 같은 지루한 일을 대신해준다.
데이터를 찾고 이해하는 계층
테이블과 컬럼이 늘어나면 데이터 파악 자체가 문제가 된다.
데이터 카탈로그는 레이크 절의 메타스토어와 개념은 비슷하지만 대상이 쿼리 엔진이 아니라 사람이다. 문서 역할을 하면서 출처, 소유자, 접근 정책 같은 비즈니스 맥락을 붙여 검색 가능하고 이해 가능하게 만든다.
시맨틱 레이어는 비즈니스 개체와 지표의 표준 정의를 보관한다. 저자가 든 예시가 명확하다. "지역별·연령대별 매출 리포트"라는 단순해 보이는 요청을 받았는데, 주문을 추적하는 테이블이 4개, 고객 테이블이 3개고 무엇을 써야 할지 모르는 상황. 게다가 지역은 어떻게 정의하며 연령대는 어떻게 나누는가. 합리적으로 가정할 수는 있지만, 지난번에 같은 리포트를 만든 사람이 같은 기준을 썼다는 보장은 없다. 시맨틱 레이어는 고객 모델이 어느 테이블의 어느 컬럼에서 오는지, EMEA에 어떤 마켓이 포함되는지, 매출 계산에 환불을 넣는지를 정의해둔다. 그리고 결정적으로 BI 도구나 AI 에이전트와 연동되어, UI에서 개체와 지표를 고르면 알아서 적절한 쿼리로 변환해준다.
데이터 리니지는 카탈로그와 짝을 이룬다. 카탈로그가 어떤 데이터가 있는지를 기술한다면, 리니지는 데이터가 파이프라인을 지나며 어떻게 변환되는지를 추적한다. 보통 오케스트레이터의 DAG, 변환 SQL 파싱, 워커가 내보내는 메타데이터에서 자동 수집된다. 정밀도에 따라 테이블 수준(gold.orders는 silver.orders와 silver.customers로 만들어짐)과 컬럼 수준(customers.life_time_value는 orders.total과 subscription_payments.amount에서 계산됨)으로 나뉜다.
용도는 셋이다. 영향도 분석(별로 안 중요해 보이는 이 컬럼을 지우면 뭐가 깨질까), 원인 추적(이 지표가 이상한데 어떤 데이터가 들어가지), 컴플라이언스(우리가 어떤 개인식별정보를 어디서 쓰고 있나). 데이터 형식은 벤더마다 다르지만, 여러 카탈로그가 지원하고 주요 처리 도구 커넥터도 많은 OpenLineage가 표준으로 부상하고 있다.
결국 데이터를 어디에 쓰는가
대시보드와 리포트가 가장 흔한 종착지다. BI 도구는 웨어하우스(또는 레이크하우스, 때로는 앱 DB에 직접) 연결해 코드 없이 차트를 만들게 해준다. 핵심 가치는 셀프서비스다. 지난주 가입자 수가 궁금할 때마다 분석가를 찌르는 대신, 덜 기술적인 사람도 UI로 직접 만들어보게 하는 것. 스케줄 리포트(대시보드를 정해진 시각에 메일이나 Slack으로 발송)나 지표가 임계치를 넘으면 알리는 기능도 흔하다.
**운영 분석(operational analytics)**은 방향이 다르다. 전통적 접근이 데이터를 모아 리포트로 만들어 임원의 전략적 판단을 돕는 것이라면, 운영 분석은 여러 부서 사람들의 일상 업무 도구 안으로 데이터를 밀어 넣는다. 사용량 집계를 HubSpot에 동기화해 영업팀이 업셀 대상을 찾게 하거나, 최근 주문·티켓·요금제를 Zendesk에 넣어 지원팀이 바로 보게 하는 식이다. 리버스 ETL이 흔한 전달 수단이지만 유일한 방법은 아니다. 웨어하우스에서 데이터를 끌어오는 사내 Customer 360 앱을 만들었다면 그것도 운영 분석이다.
애드혹·탐색적 분석은 배치도 실시간도 아니다. 지난주 가입자가 왜 떨어졌는지, 이 이상한 급증이 진짜인지 같은 일회성 질문에 앉아서 데이터를 뒤지는 일이다. 처리가 단순 필터링과 집계를 넘어서기 때문에 리포팅 도구로는 금방 한계가 온다. 한 세트의 연산으로 이상을 찾고, 결과에 따라 다른 연산을 적용하는 식으로 진행되기 때문이다.
여기서 노트북이 별도로 강조된다. 마크다운과 코드(그리고 SQL 셀 같은 다른 셀 타입)를 한 파일에 섞을 수 있고, 코드 셀이 이미지·인터랙티브 차트·테이블을 출력한다. 코드 옆에서 실행 결과를 바로 보며 점진적으로 분석할 수 있어 탐색적 분석에 잘 맞고, 결과를 발표하기에도 좋다.
임베디드 분석은 데이터를 내 제품의 기능으로 내보내는 경우다. 마켓플레이스를 운영한다면 판매자가 무엇이 잘 팔리는지, 고객이 어디서 오는지 보고 싶어 한다. 필터가 제한된 차트 5개 정도라면 직접 만들어도 되지만, 사용자가 복잡한 질의를 하길 원한다면 전용 도구가 낫다. 이 조합에서 인증·인가는 내 앱이 맡고, 질의와 차트 렌더링은 임베디드 분석 솔루션이 맡는다.
데이터 자체가 제품인 경우도 있다. 여러 블록체인 데이터를 수집·가공·인덱싱해 분석가에게 판매하거나, 검색 결과를 수집해 SEO 담당자에게 파는 식이다. 이 경우 파는 게 데이터와 질의 접근권이므로 수집 파이프라인의 안정성과 질의 성능이 곧 제품 품질이다.
데이터 거버넌스
마지막 장은 기술과 가장 거리가 먼 대신 중요도는 낮지 않다. 회사가 수집하는 데이터에는 개인식별정보나 건강 데이터처럼 아무나 읽어선 안 되는 것이 섞인다. 거버넌스는 누가 접근할 수 있는지, 누가 실제로 접근했는지, 소유자가 누구인지, 잊힐 권리 같은 프라이버시 요구를 어떻게 처리하는지, 데이터가 물리적으로 어디 저장되고 얼마나 보관되는지를 통제한다.
기술이 일부를 도울 수는 있다. 권한은 웨어하우스 레벨에서 설정할 수 있고, 카탈로그에 소유자 정보를 담을 수 있고, 리니지로 개인정보 사용 경로를 추적할 수 있다. 하지만 본질적으로는 사람과 프로세스의 문제이고 법무·컴플라이언스·보안 팀에 더 가깝다는 게 저자의 결론이다.
기능별 도구 한눈에 정리
| 역할 | 도구 |
|---|---|
| 데이터 웨어하우스 (매니지드) | Snowflake, BigQuery, Redshift |
| 데이터 웨어하우스 (오픈소스·셀프호스팅) | ClickHouse, Apache Doris, StarRocks |
| 데이터 레이크 스토리지 | Amazon S3, Google Cloud Storage, Azure Blob Storage |
| 데이터 레이크 (매니지드) | Azure Data Lake, Snowflake |
| 메타데이터 카탈로그 (쿼리 엔진용) | Hive Metastore, AWS Glue Data Catalog, Unity Catalog |
| 쿼리 엔진 | Apache Spark, Trino, Amazon Athena |
| 레이크하우스 테이블 포맷 | Apache Iceberg, Delta Lake, Apache Hudi |
| 레이크하우스 (매니지드) | Google Lakehouse for Apache Iceberg(구 BigLake), Databricks(Delta Lake), IBM watsonx.data(Iceberg) |
| 파일 포맷 | CSV, Apache Parquet, Apache ORC, Apache Avro |
| 메모리 포맷 | Apache Arrow |
| 데이터 수집 | Fivetran, Airbyte, dlt |
| CDC (독립) | Debezium |
| SQL 변환 | dbt, SQLMesh |
| 로컬 데이터프레임 | pandas, Polars, DataFusion, DataFrames.jl, data.frame, tablesaw |
| 로컬 OLAP | DuckDB |
| 분산 처리 | Apache Spark, Dask, Ray, Apache Hadoop(레거시) |
| 이벤트 스트리밍 플랫폼 | Apache Kafka, Apache Pulsar, Redpanda, AWS Kinesis Data Streams |
| 스트림 처리 | Apache Flink, Kafka Streams, Spark Structured Streaming, Google Cloud Dataflow, Azure Stream Analytics |
| 오케스트레이션 | Apache Airflow, Dagster, Prefect, Luigi(구버전) |
| 파이프라인 모니터링 | Prometheus, Grafana, ELK |
| 데이터 품질 (수동 정의) | Great Expectations, dbt tests |
| 데이터 품질 (자동 탐지) | Monte Carlo, Bigeye, Metaplane |
| 실시간 OLAP 서빙 | Apache Druid, Apache Pinot, ClickHouse |
| 리버스 ETL | Airbyte Data Activation, Fivetran Activations(구 Census), Hightouch, RudderStack |
| 데이터 카탈로그 (사람용) | Unity Catalog, DataHub, OpenMetadata |
| 시맨틱 레이어 | LookML(Looker), Cube, dbt Semantic Layer, Unity Catalog |
| 리니지 표준 | OpenLineage |
| BI · 리포팅 | Tableau, Power BI, Looker, Metabase |
| 임베디드 분석 | Metabase, Looker, Tableau, Sisense, Luzmo |
| 노트북 | Jupyter, Google Colab, Deepnote, marimo |
| 데이터용 IDE | Spyder, RStudio |
표를 볼 때 헷갈리기 쉬운 지점 셋.
웨어하우스와 레이크는 제품 대 제품이 아니라 구조가 다르다. 웨어하우스는 저장과 질의를 한 시스템이 관리하고 자체 엔진에 묶여 있다. 레이크는 스토리지(S3), 메타스토어(Glue), 쿼리 엔진(Trino)을 각각 골라 조립한다. 레이크 관련 행이 여러 줄로 쪼개진 이유다.
Iceberg와 Delta Lake는 플랫폼이 아니라 테이블 포맷이다. 레이크하우스 도입은 플랫폼 선택과 포맷 선택이라는 두 개의 결정이 겹쳐 있는 일이다. Databricks는 Delta Lake를, Google과 IBM 제품은 Iceberg를 쓴다.
카탈로그가 두 번 나오는 건 오타가 아니다. 쿼리 엔진이 읽는 메타스토어와 사람이 읽는 데이터 카탈로그는 개념은 닮았지만 대상이 다르다. Unity Catalog가 메타스토어·카탈로그·시맨틱 레이어에 모두 등장하는 건 여러 역할을 겸하기 때문이다.
정리
이 글의 값어치는 도구 목록이 아니라 경계선에 있다. 웨어하우스는 저장과 질의가 묶여 있고 레이크는 분리되어 있다는 것, 테이블 포맷이 레이크를 레이크하우스로 만든다는 것, Kafka는 저장만 하고 처리는 Flink가 한다는 것, dbt는 SQL을 컴파일할 뿐 데이터를 만지지 않는다는 것, 오케스트레이터는 배치 전용이라 스트리밍에는 안 맞는다는 것. 이 구분만 잡혀도 데이터 팀 회의에서 무슨 말인지는 따라갈 수 있다.
반대로 이 글에 없는 것도 분명하다. 배포와 CI, 데이터 테스트 전략, 동일 카테고리 내 도구 선택 기준은 저자가 처음부터 범위 밖이라고 선을 그었다. 지도를 얻는 용도로 읽고, 실제 선택은 다른 자료에서 찾는 게 맞다.
- 데이터엔지니어링
- 데이터파이프라인
- 데이터레이크하우스
- ETL
- 데이터플랫폼
아직 댓글이 없습니다.