Node.js 충돌 방지: 15MB RAM으로 10GB 파일 처리하기

발행: (2026년 5월 1일 AM 02:00 GMT+9)
3 분 소요
원문: Dev.to

Source: Dev.to

문제: “Array.map()” 함정

대부분의 개발자는 데이터를 다음과 같이 처리합니다:

const data = JSON.parse(fs.readFileSync('huge-file.json')); // ❌ 여기서 메모리 급증
const processed = data.map(record => transform(record));    // ❌ 여기서 메모리 두 배 증가
fs.writeFileSync('output.json', JSON.stringify(processed));

작은 파일에서는 동작하지만 선형적으로 확장됩니다. 1 GB 파일은 입력과 출력을 저장하기 위해 최소 2 GB RAM이 필요합니다.

해결책: 상수 메모리 (O(1))

Data‑Genie는 데이터를 연속 스트림으로 취급합니다. 배열을 로드하는 대신 Async Iterators를 사용해 한 레코드씩 가져와 변환하고 목적지에 푸시합니다.

그 결과? 100 KB 파일과 같은 양의 RAM으로 100 GB 파일을 처리할 수 있습니다.

데이터 크기 비교

데이터 크기순진한 접근법 (Array 기반)Data‑Genie (스트리밍)
100 KB~10 MB RAM~10 MB RAM
100 MB~150 MB RAM~12 MB RAM
10 GBCRASH (OOM)~15 MB RAM

다양한 포맷을 위한 통합 API

import { CSVReader, SQLWriter, Job } from '@pujansrt/data-genie';

const reader = new CSVReader('input.csv');
const writer = new SQLWriter(db, 'users');

await Job.run(reader, writer);

데이터가 CSV, JSON, Excel, Parquet, 혹은 SQL 데이터베이스에 있든 코드는 동일하게 보입니다.

내장된 Dead Letter Queue (DLQ)

실제 환경에서는 데이터가 “더럽습니다.” 하나의 형식이 잘못된 행이 전체 작업을 중단시킬 수 있습니다. Data‑Genie는 자동으로 실패한 레코드를 “poison” 파일로 전송하면서 메인 작업은 계속 진행되는 내장 DLQ를 제공합니다.

import { z } from 'zod';
import { CSVReader, JsonWriter, SchemaValidatingReader } from '@pujansrt/data-genie';

const schema = z.object({
  id: z.coerce.number(),
  email: z.string().email(),
});

const reader = new CSVReader('input.csv');
const validator = new SchemaValidatingReader(reader, schema)
  .setDLQ(new JsonWriter('failed_rows.json'));

EventEmitter를 활용한 실시간 진행 상황

최신 업데이트에서는 Job 클래스를 EventEmitter로 전환해 폴링 없이 진행률 바나 대시보드를 만들 수 있습니다.

import { Job, CSVReader, JsonWriter } from '@pujansrt/data-genie';

const job = new Job(new CSVReader('users.csv'), new JsonWriter('output.json'));

job.on('progress', (metrics) => {
  console.log(`Processed ${metrics.recordCount} records...`);
});

await job.run();

설치

npm install @pujansrt/data-genie

사용 예시

import { CSVReader, JsonWriter, Job } from '@pujansrt/data-genie';

const reader = new CSVReader('users.csv');
const writer = new JsonWriter('output.json');

(async () => {
  const metrics = await Job.run(reader, writer);
  console.log(`Processed ${metrics.recordCount} records in ${metrics.durationMs} ms`);
})();

추가 자료

0 조회
Back to Blog

관련 글

더 보기 »

Task schedule은 쓰레기다

개요 특정 시간에 TypeScript 파일을 실행합니다. 이 라이브러리는 세 가지 스케줄링 방법을 지원합니다: - interval – 설정된 간격으로 반복 실행 - atTime – …