← 포트폴리오로 돌아가기

KIM 수치예보 모델 실시간 데이터 파이프라인 구축

2026.03 ~ 현재·설계 / 개발 / 운영·한국전자기술연구원 (KETI)

기상 수치예보 모델 전환(GRIB2 → NetCDF)에 따른 실시간 데이터 파이프라인을 처음부터 설계·구축하고, 핵심 성능 병목을 근본 원인 분석을 통해 해결한 프로젝트.

처리 속도 개선

17x

메모리 사용률

98% → 50% 이하로

일 처리 데이터

392파일 / 51GB

격자 해상도 향상

3.84배


데이터 흐름

기상청 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 백업을 비동기로 처리합니다.

문제를 어떻게 정의하고, 왜 이 방법을 선택했는지

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 한 줄로 에이전트 배포 가능.


Apache KafkaPyArrowHDFSDockerDocker ComposenetCDF4numpyKafka ConnectPrometheusGrafanaAnsible

← 포트폴리오로 돌아가기