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의 핵심 개념이지만 실제로 사용해보니 왜 중요한지 체감할 수 있었다. 배치 작업에서는 필수적인 패턴이다.