Node.js 스트림으로 대용량 CSV 파일 처리하기

문제 상황

재택근무로 전환되면서 사용자 데이터 분석 요청이 급증했다. 기존에는 fs.readFileSync로 CSV 파일을 전부 읽어서 처리했는데, 200MB 파일을 처리하다가 메모리 부족으로 프로세스가 죽는 현상이 발생했다.

// 기존 코드 - 전체를 메모리에 로드
const data = fs.readFileSync('users.csv', 'utf-8');
const lines = data.split('\n');
lines.forEach(line => processLine(line));

스트림 기반 처리로 전환

Node.js의 스트림 API를 사용하면 파일을 청크 단위로 읽어서 처리할 수 있다. readline 모듈과 조합해 라인별로 처리하도록 수정했다.

const fs = require('fs');
const readline = require('readline');

async function processLargeCSV(filePath) {
  const fileStream = fs.createReadStream(filePath);
  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });

  let count = 0;
  for await (const line of rl) {
    if (count === 0) {
      count++;
      continue; // 헤더 스킵
    }
    await processLine(line);
    count++;
  }
  
  console.log(`처리 완료: ${count}건`);
}

결과

  • 메모리 사용량: 800MB → 80MB로 감소
  • 200MB CSV 파일 안정적 처리 가능
  • 백프레셔 자동 처리로 DB 부하도 조절됨

스트림은 Node.js의 핵심 개념이지만 실제로 사용해보니 왜 중요한지 체감할 수 있었다. 배치 작업에서는 필수적인 패턴이다.

Node.js 스트림으로 대용량 CSV 파일 처리하기