Back to all articles
DevelopmentData FormatStreaming
·

대용량 데이터와 실시간 스트리밍을 위한 NDJSON

NDJSON(Newline Delimited JSON)의 개념과 활용법을 알아보세요. 대용량 데이터와 실시간 스트리밍을 효율적으로 처리하는 텍스트 기반 데이터 포맷입니다.

대용량 데이터와 실시간 스트리밍을 위한 NDJSON

NDJSON은 Newline Delimited JSON 의 약어로, 각 줄마다 하나의 JSON 객체가 위치하는 텍스트 기반 데이터 포맷입니다. 일반 JSON 과 달리 NDJSON 은 큰 데이터셋이나 스트리밍 데이터를 다룰 때 유용하며, 한 번에 전체 데이터를 메모리에 적재하지 않고 한 줄 씩 처리할 수 있는 장점이 있습니다.

 {"some":"thing"}
 {"foo":170,"bar":false,"quux":true}
 {"may":{"include":"nested","objects":["and","arrays"]}}

정말 이게 끝입니다! JSON Array 와 유사해 보이지만 처음과 끝에 대괄호가 없고 각 객체가 쉼표 대신 개행으로 구분 된다는 차이점이 있습니다.

NDJSON의 특징

행 단위의 데이터 처리

NDJSON 파일은 각 줄이 독립적인 JSON 객체로 구성되어 있기 때문에, 파일의 일부분만 읽어서 처리할 수 있습니다. 이러한 특성 덕분에 메모리를 효율적으로 사용하여 대용량 데이터 처리나 스트리밍 처리에 유리합니다.

또한 UNIX Pipes 와 궁합도 좋습니다. 마지막 로그를 보려면 어디까지 불러와야 하나 고민 되셨죠?

tail -n 1 log.ndjson

끝났습니다.

간단한 파싱 구조

각 줄이 JSON 객체 이므로, 줄 단위로 읽어 JSON 파서를 통해 쉽게 객체로 변환할 수 있습니다. 이는 데이터의 직렬화/역직렬화 작업을 간편하게 만들어 줍니다. 단, 처리할 때 빈 줄이 있는 경우 라던가 전체 객체 중 일부만 파싱에 실패하는 등 예외 처리에 대한 고려가 필요합니다.

유연한 데이터 추가

JSON Array 와 달리 새로운 데이터 객체를 추가할 때 마다 파일 전체를 읽을 필요 없이 파일의 끝에 단순히 추가하면 되므로, 실시간 로그 기록이나 데이터 추가 작업에 매우 효율적 입니다. 마찬가지로 최근에 추가된 데이터를 조회하기도 쉽습니다.

// json
const data = fs.readFileSync("./log.json", "utf8");
const json = JSON.parse(data);
json.push({ timestamp: new Date().toISOString() });

fs.writeFileSync("./log.json", JSON.stringify(json), "utf8");

// ndjson
const newEntity = { timestamp: new Date().toISOString() };
fs.appendFileSync("./log.json", JSON.stringify(newEntity), "utf8");

정리

NDJSON 은 대용량 데이터 처리, 스트리밍 및 로그 기록에 매우 유용한 데이터 포맷입니다. 각 줄이 독립적인 JSON 객체로 구성되어 있기 때문에, 데이터를 한 줄 씩 처리할 수 있는 유연성을 제공합니다.

참고 : NDJSON 공식 스펙