3P by neo 5달전 | favorite | 댓글 2개

날씨 데이터 웨어하우스 구축하기 파트 1: TimescaleDB에 1조 행의 날씨 데이터 로딩하기

우리가 하고 있는 일의 의미

날씨 데이터 웨어하우스를 구축하는 이유

  • 기후 변화의 징후를 분석하기 위해 전 세계의 과거 날씨 데이터를 모아 분석하는 것이 좋겠다고 생각함
  • 대규모 날씨 데이터 웨어하우스가 있다면, 자카르타가 실제로 더 따뜻해졌거나 폭풍이 심해졌는지, 칠레가 전반적으로 더워지거나 구름이 많아지는지 등을 지역별로 파악할 수 있음
  • 이를 통해 지구상 어느 지역이 가장 많은 기후 변화를 경험했는지, 어떤 종류의 변화가 있었는지 파악 가능
  • 전 세계적으로 이런 분석을 하려면 데이터 웨어하우스 질의 속도를 높여야 하며, 데이터가 매우 많음
  • 첫 단계는 데이터를 PostgreSQL에 로딩하는 것임. TimescaleDB로 시계열 쿼리 속도를 높이고, PostGIS로 지리공간 쿼리 속도를 높이는 것이 유망해 보임

데이터 소개

  • 실제 관측 데이터가 아닌 ERA5 기후 재분석(climate reanalysis) 제품 데이터 사용
  • ERA5는 관측 데이터로 제약을 받는 기후 모델 실행 결과로, 관측이 많은 곳은 관측과 유사하고 관측이 없는 곳은 물리적으로 일관되며 기후 통계와 일치
  • ERA5는 1940년부터 전 지구를 0.25도 해상도로 시간당 데이터 제공. 기온, 강수량, 운량, 풍속 등 변수별로 7억 5천만 행 이상의 데이터
  • 이 데이터를 관계형 DB에 빠르게 삽입하는 것은 쉽지 않음

데이터 삽입 방법

단일 행 insert 문

  • 가장 간단한 방법이지만 매우 느림. 초당 3000건 삽입으로 전체 데이터 로딩에 약 8년 소요
  • 구문 분석, 테이블/컬럼 검증, 실행 계획, 테이블 잠금, 버퍼 쓰기, 디스크 쓰기, 커밋 등 오버헤드가 큼

다중 값 insert

  • 한 insert 문으로 여러 행 삽입. 네트워크, 구문 분석, 실행 계획 오버헤드 감소
  • psycopg3가 초당 25,000~30,000건으로 가장 빠름
  • 하지만 여전히 전체 데이터 로딩에 약 10개월 소요

copy 문

  • 대량 데이터 로딩에 최적화된 방법. CSV나 바이너리 파일에서 직접 읽어서 구문 분석, 계획, WAL 사용 최적화
  • 이미 CSV가 있다면 간단히 copy 문 사용 가능
  • psycopg3의 copy는 초당 10만건 이상 삽입 가능. 오버헤드 포함해도 3개월 내 전체 데이터 로딩 가능
  • copy로 장시간 고속 삽입 시 병목 현상 주의 필요

병렬 copy

  • 여러 copy 작업을 병렬로 수행해 속도 향상
  • 단일 테이블 삽입은 병렬화 효과가 크지 않아 16개 worker 이상은 성능 개선 없음

외부 도구 사용

  • pg_bulkload와 timescaledb-parellel-copy 벤치마크
  • pg_bulkload가 빠르지만 기본적으로 WAL을 건너뛰기 때문에 안전하지 않음
  • timescaledb-parallel-copy는 다중 worker로 초당 30만건 이상 안전하게 삽입 가능

PostgreSQL 설정 조정

  • fsync와 full_page_writes를 끄면 디스크 쓰기를 피해 더 빠르게 할 수 있으나 위험
  • unlogged 테이블도 WAL을 사용하지 않아 빠르지만 크래시 시 잘림. hypertable은 unlogged가 될 수 없음

최상의 방법은?

  • psycopg3로 직접 hypertable에 copy하는 것이 가장 좋음. CSV 파일은 timescaledb-parallel-copy 사용
  • 병렬화는 12~16개 worker가 적당
  • 규칙을 해제하면 초당 46만건까지 가능하지만 위험
  • 하드웨어 업그레이드로 더 빠른 속도 가능
  • ClickHouse가 더 빠를 수 있지만 PostgreSQL을 배우고 싶어서 TimescaleDB 선택
  • 초당 46만건이면 20일 내 전체 데이터 로딩 가능

GN⁺의 의견

  • ERA5 데이터를 관계형 DB에 넣어서 분석하려는 시도가 흥미롭네요. 기존에는 xarray나 dask로 NetCDF 데이터를 직접 분석하는 게 일반적이었는데, 데이터 웨어하우스를 구축하면 더 복잡한 질의를 수행할 수 있겠어요.
  • 저자의 하드웨어 스펙이 5년 전 것인데도 초당 46만건을 넣을 수 있다는 점이 인상적이에요. 최신 하드웨어라면 초당 100만건도 가능할 거예요. 하지만 fsync와 full_page_writes를 끄는 것은 DB 무결성을 해칠 수 있으니 주의해야겠네요.
  • PostgreSQL의 병렬 처리 기능이 단일 테이블에는 크게 도움이 안되는 것 같아요. 병렬 처리와 파티셔닝을 결합한다면 더 높은 성능을 낼 수 있을 거예요. Citus 같은 Postgres의 수평적 확장 솔루션도 고려해볼 만해요.
  • 기후 변화 분석에 ERA5 데이터가 활용될 수 있다는 점이 흥미로워요. 관측 데이터가 부족한 지역의 과거 기후를 분석할 수 있겠네요. 하지만 ERA5는 어디까지나 모델 결과물이라는 한계가 있어요. 관측 데이터로 보정하긴 했지만, 불확실성이 있다는 점을 감안해야겠어요.
  • 분석 플랫폼으로는 Snowflake나 BigQuery 같은 클라우드 데이터 웨어하우스를 쓰는 게 일반적이에요. 하지만 저자처럼 자체 하드웨어를 다루며 배우는 것도 의미가 크죠. 특히 기후 데이터는 용량이 크기 때문에 클라우드로 옮기는 게 쉽지 않아요. 앞으로 실제 분석 결과가 기대돼요.

GN+의견이 존댓말이네요..?

Hacker News 의견

요약하면 다음과 같음:

  • 지리공간 데이터 분석 시 좌표계(CRS)와 지도 투영법을 이해하는 것이 중요함. 대규모 지리공간 작업엔 Google BigQuery가 가장 뛰어남.

  • 관계형 DB가 격자 기상 데이터에 적합한지는 실험을 통해 알아봐야 함.

  • Timescale에서 Hypertable이 느린 이유는 기본으로 생성되는 timestamp 컬럼 인덱스 때문일 수 있음. create_default_indexes=>false 옵션으로 인덱스 생성을 건너뛰거나 데이터 입력 후 인덱스를 만드는 게 좋음.

  • 기상 데이터를 RDBMS로 옮기는 게 어떤 이점이 있는지 분석이 부족함. Serverless + 객체 스토리지로도 매우 빠른 응답 속도를 얻을 수 있음.

  • ERA5 같은 대부분의 기상/기후 데이터셋은 규칙적인 위경도 그리드로 구성되어 있어 구조를 완전히 파괴하는 건 좋지 않음. ARCO-ERA5 같이 클라우드에 최적화된 버전을 활용하는 게 나음.

  • PostgreSQL에서 WAL을 끄고 VACUUM FREEZE 명령을 주기적으로 실행하면 대량 데이터 로드 시 성능을 더 높일 수 있음.

  • COPY를 사용할 수 없다면 행을 JSON 문자열로 인코딩해 단일 쿼리 파라미터로 보내고 json_to_recordset을 사용하는 것도 좋은 방법임.