Iceberg와 Flink로 데이터 파이프라인(Data Pipeline) 성능 12배 향상!

by DD
2개월 전
조회수 24

HBase와 Hive 기반 ETL의 데이터 반영 지연 문제를 해결하기 위해 Iceberg 테이블 형식을 도입

Apache Flink를 활용하여 데이터의 최신성 보장(Data Freshness), 정확히 한 번 처리(Exactly-Once)를 구현

Flink 쿠버네티스 오퍼레이터(Kubernetes Operator)를 통해 배포 및 운영 효율성을 확보하고, 데이터 반영 속도 12배 향상 달성

위임 토큰 프레임워크(Delegation Token Framework) 도입 및 식별자 설정 누락 문제 해결 등, 안정적인 운영 환경 구축에 집중

ID 기반 파티셔닝(ID-based Partitioning)을 통해 HDFS I/O 병목 현상 해결 및 읽기 성능(Read Performance) 개선

Iceberg 테이블 형식 도입 배경

기존 HBase와 Hive 기반 ETL 시스템은 전체 데이터 덤프(Full Dump) 방식의 한계로 인해 데이터 반영 지연 문제를 겪었다. 데이터 변경 시마다 전체 데이터를 다시 써야 하는 구조는 데이터 규모가 커질수록 반영 시간과 비용을 증가시키는 주요 원인이었다. Hadoop 리소스 부족 상황까지 겹쳐 데이터 최신성 확보에 어려움을 겪었다. 이러한 문제를 해결하기 위해 증분 처리(Incremental Processing)가 가능한 Iceberg 테이블 형식을 도입했다.

Flink를 선택한 이유: 데이터 최신성 및 정확히 한 번 처리

Flink는 데이터 최신성 보장, 종단 간 정확히 한 번 처리(Exactly-Once), 장애 허용(Fault Tolerance) 및 상태 관리라는 세 가지 필수 요건을 충족하기 위해 선택되었다. 특히, 마이크로 배치(Micro-Batch) 방식의 Spark Streaming(Structured Streaming)과 달리, Flink는 네이티브 스트리밍(Native Streaming) 엔진으로, 이벤트 단위 처리를 통해 데이터 최신성 보장 및 정확히 한 번 처리를 구현했다. Flink의 체크포인트(Checkpoints)와 2단계 커밋(Two-Phase Commit, 2PC) 연동을 통해 데이터 누락을 방지했다.

Flink 쿠버네티스 오퍼레이터(Kubernetes Operator) 도입

Flink 클러스터의 안정적인 배포 및 운영을 위해 네이티브 쿠버네티스 방식과 Flink 쿠버네티스 오퍼레이터(Kubernetes Operator) 방식을 비교 분석했다. Flink 쿠버네티스 오퍼레이터는 Flink 운영에 필요한 모든 요소를 커스텀 리소스로 추상화하여, 설정 및 운영의 편의성을 제공했다. GitOps 기반 운영을 통해 현재 실행 중인 Flink 잡 상태와 Git에 정의된 설정 파일 간의 일관성을 보장했다. FlinkDeployment와 FlinkSessionJob을 활용하여 유연한 리소스 관리 및 스케일 아웃(Scale-out)을 용이하게 했다.

데이터 최신성 보장을 위한 아키텍처

CDC 데이터와 보정 데이터를 별도의 Kafka 토픽으로 분리하여 수신하는 구조를 설계했다. KeyedStream API를 활용하여 상품 ID별로 이전 처리 데이터의 `updateDate`를 상태값(State)으로 저장하고, 과거 데이터는 무시하며 최신 데이터만 Iceberg 테이블에 병합했다. 보정 데이터는 Iceberg 테이블의 데이터가 최신 상태와 어긋났을 때, MongoDB에서 해당 상품의 `fullDocument`를 다시 조회하여 반영하는 방식으로 생성되었다. 이러한 아키텍처는 컨슈머 랙(Consumer Lag) 발생 시에도 데이터 무결성을 보장한다.

윈도 연산을 활용한 보정 데이터 생성 파이프라인 최적화

보정 데이터 생성 파이프라인에서 대량의 보정 요청을 효율적으로 처리하기 위해 윈도(Window) 연산을 최적화했다. 키 기반 윈도(Keyed Window)를 채택하여 Flink의 분산 처리 능력을 극대화하고, 키 분산을 최적화하여 특정 오퍼레이터(Operator)에 부하가 집중되는 문제를 해결했다. 커스텀 트리거(Custom Trigger)를 구현하여 MongoDB에 과부하를 주는 것을 방지했다. 이 커스텀 트리거는 시간 및 데이터 개수를 기준으로 윈도를 방출하여, 안정적인 배치 처리를 가능하게 했다.

트러블슈팅: 위임 토큰, 식별자 설정, 파일 최적화

Flink와 Iceberg 사용 과정에서 겪었던 문제와 해결 과정을 공유한다. 위임 토큰 프레임워크(Delegation Token Framework)를 도입하여 Kerberos 인증 문제를 해결하고, HadoopSecurity 모듈 누락 및 Kafka Kerberos 인증 간섭 문제를 해결했다. 식별자(Identifier) 칼럼 설정 누락으로 인한 데이터 유일성(Uniqueness) 보장 실패 및 읽기 성능 저하 문제를 해결하기 위해 `identifier-field-ids`와 `equalityFieldColumn`을 정의했다. rewrite_data_files 프로시저(Procedure) 최적화를 위해 Spark 메모리 할당 전략 수정, CPU 기아(Starvation) 현상 방지, HDFS I/O 부하 방지 등의 노력을 기울였다. 최종적으로 ID 기반 파티셔닝(ID-based Partitioning)을 도입하여 HDFS I/O 병목 현상을 해결하고 읽기 성능을 개선했다.

Hive에서 Iceberg로: 데이터 반영 속도 12배 향상의 비밀