Project
KIM 수치예보 모델 실시간 데이터 파이프라인 구축
Overview
기상 수치예보 모델 전환(GRIB2 → NetCDF)에 따른 실시간 데이터 파이프라인을 처음부터 설계·구축하고, 핵심 성능 병목을 근본 원인 분석을 통해 해결한 프로젝트.
Key Results
처리 속도 개선
17x
메모리 사용률
98% → 50% 이하로
일 처리 데이터
392파일 / 51GB
격자 해상도 향상
3.84배
Architecture
데이터 흐름기상청 FTP
NetCDF 392파일/일
Kafka Connect
FTP Source Connector
Kafka Cluster
3-node, 3개 토픽
Consumer
Docker ×10 병렬
HDFS + NAS
Parquet 적재 + gzip 백업
etc(지표면)와 prs(기압면)를 별도 토픽과 Consumer로 완전 분리해 장애가 서로에게 전파되지 않도록 설계. HDFS 적재 완료 후 이벤트를 발행해 NAS 백업을 비동기로 처리합니다.
Technical Decisions
문제를 어떻게 정의하고, 왜 이 방법을 선택했는지
PySpark → PyArrow 전환
기존 GRIB2 파이프라인과 동일한 구조를 썼지만 KIM은 격자 크기가 3.8배(47만 → 180만) 커서 JVM Old Gen 임계점을 초과. createDataFrame의 176MB 단일 task가 GC thrashing을 유발하고, CommitFailedError와 Consumer rebalance가 연쇄 발생해 처리 시간이 4분~57분으로 들쭉날쭉했습니다.
Spark Cluster 전환도 검토했지만 createDataFrame이 Driver 측 작업이라 클러스터로도 해결 불가. 문제의 근원인 JVM 자체를 제거하기로 결정하고 PyArrow로 전환했습니다. 메시지 분할 방식도 직렬화 총량이 동일해 의미 없음을 확인 후 기각.
파일당 처리 시간 17배 개선(~4분 → ~14초), 메모리 사용률 98% → 50% 이하로 안정화, CommitFailedError·HDFS lease 만료 0건.
etc / prs 독립 파이프라인 분리 설계
지표면(etc)과 기압면(prs) 데이터를 단일 파이프라인으로 묶으면 한쪽 장애가 전체 수집에 영향을 줍니다. ML 모델 학습에 두 데이터가 모두 필요한 상황에서 장애 영향을 최소화할 방법이 필요했습니다.
etc와 prs를 별도 Kafka 토픽과 Consumer 그룹으로 완전 분리. 각 파이프라인이 독립적으로 배포·운영·스케일되도록 설계하고, NAS I/O 병목을 고려해 백업 파이프라인은 단일 파티션으로 구성했습니다.
장애 영향 범위 50% 감소. 한쪽 파이프라인 장애 시 다른 쪽 정상 운영 유지.
Prometheus + Grafana로 모니터링 스택 전환
기존 Elasticsearch + Burrow + Telegraf + srvstatus 구성은 Elasticsearch 단독으로 수 GB RAM을 점유하고, 관리 포인트가 4개 툴에 분산되어 있어 새 서버 추가 시 에이전트 설치가 수작업이었습니다.
경량 Prometheus + Grafana로 통합. Kafka Exporter(Consumer lag), Node Exporter(서버 메트릭), JMX Exporter(Connector 상태)를 도입하고 Ansible playbook으로 Hadoop 14대 + Kafka 3대 = 총 17대에 일괄 자동 배포했습니다.
Elasticsearch 메모리 부담 해소, 모니터링 스택 단일화, 신규 서버 추가 시 Ansible 한 줄로 에이전트 배포 가능.
Tech Stack