Node.js 스트림으로 대용량 CSV 파일 처리 최적화
문제 상황
데이터 분석팀에서 100GB 규모의 CSV 로그 파일을 파싱해 DB에 적재하는 작업을 요청했다. 기존에는 fs.readFile로 전체를 메모리에 올려 처리했는데, 이번엔 파일 크기가 너무 커서 메모리 부족으로 프로세스가 죽었다.
// 기존 방식 - 메모리 부족 발생
const data = fs.readFileSync('large-log.csv', 'utf-8');
const lines = data.split('\n'); // 메모리 초과
스트림 기반 처리로 전환
Node.js의 Readable Stream을 활용해 파일을 청크 단위로 읽어 처리하도록 변경했다. readline 모듈을 사용하면 라인 단위 처리가 간단하다.
const fs = require('fs');
const readline = require('readline');
const processFile = async (filePath) => {
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
let batch = [];
for await (const line of rl) {
const parsed = parseLine(line);
batch.push(parsed);
if (batch.length >= 1000) {
await insertToDB(batch);
batch = [];
}
}
if (batch.length > 0) {
await insertToDB(batch);
}
};
결과
메모리 사용량이 약 4GB에서 200MB로 감소했고, 처리 시간도 안정적으로 유지됐다. 배치 사이즈를 1000으로 설정해 DB 부하도 분산시켰다.
대용량 파일 처리 시 스트림 패턴은 필수다. 특히 재택 환경에서 로컬 머신 리소스가 제한적일 때 더 유용했다.