← 모든 글

Pandas 가 메모리에서 죽는 시점

월별 운영 로그를 한 번에 분석하려다 2GB VM 의 OOM Killer 와 만났다.

월별 운영 로그 파일 3개 (각 1.2GB) 를 한 번에 합쳐서 분석하려 했다.

df = pd.concat([pd.read_csv(f) for f in files])

3분 후 SSH 세션이 끊겼다. dmesg 를 보니 Out of memory: Killed process — Pandas 가 메모리 12GB 까지 부풀어 있었다. 2GB VM 에서.

CSV 가 메모리에서 왜 5배가 되나

  • CSV 의 숫자 컬럼은 기본 int64 (8 byte/cell) — 원본 텍스트 “1” (1 byte) 대비 8배
  • 문자열 컬럼은 Python object 로 들어감 — 한 글자에 ~50 byte
  • pd.concat 의 임시 버퍼가 한 번 더

해결

세 가지를 같이 했다.

  1. dtype 명시: read_csv(f, dtype={'count': 'int32', 'kind': 'category'})
  2. 청크 단위 처리: read_csv(f, chunksize=100_000) → 청크 별로 집계 → 마지막에 concat
  3. 필요한 컬럼만 읽기: usecols=['ts', 'kind', 'count']

메모리 사용량이 12GB → 380MB.

더 큰 교훈

처음부터 DuckDB 를 썼다면 이 글이 없었을 거다.

import duckdb
df = duckdb.sql("""
  SELECT date_trunc('day', ts) d, kind, sum(count)
  FROM read_csv('logs/*.csv')
  GROUP BY 1, 2
""").df()

같은 작업이 메모리 200MB, 9초. Pandas 로 청크 처리한 380MB · 47초 와 비교가 안 된다.

다음에는 다르게 할 한 가지

CSV 파일이 1GB 를 넘는 순간 Pandas 의 직관적인 syntax 를 포기한다. DuckDB 의 SQL 한 줄이 Pandas 의 청크 처리보다 항상 더 단순하다.


🛒 이 글과 어울리는 추천 상품

위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.