우리 모두 JSON과 CSV에는 익숙하지만, 수 GB에 달하는 대용량 JSON 파일을 처리하다가 메모리가 폭발해 다운되거나, CSV로 중첩된 다층 데이터를 기록할 때 이스케이프 문자로 고통받은 적이 있으신가요?
최신 AI 학습 및 대용량 데이터 처리 분야에서 조용히 표준으로 자리 잡고 있는 데이터 포맷이 있습니다. 바로 JSONL(JSON Lines) 입니다.
JSONL의 핵심 가치: 기존 JSON의 스트리밍 읽기 불가와 CSV의 중첩 구조 미지원이라는 두 가지 단점을 완벽히 해결!
JSONL이란 무엇인가? 1분 만에 이해하는 “한 줄에 하나의 JSON” 핵심 정의
JSONL의 풀네임은 JSON Lines입니다(때로는 NDJSON, 즉 Newline Delimited JSON으로도 불립니다). 핵심 개념은 매우 명확합니다: 각 줄이 하나의 독립적이고 완전한 JSON 객체라는 점입니다.
기존의 JSON 파일에서는 최외곽에 거대한 대괄호 []가 모든 데이터를 감싸고 있으며, 객체 사이는 쉼표 ,로 구분해야 합니다. 반면 JSONL은 최외곽 대괄호와 쉼표를 완전히 없애고 줄바꿈 기호 \n를 사용하여 데이터를 구분합니다.

3대 주요 데이터 포맷 비교
더욱 직관적으로 이해할 수 있도록 JSONL, JSON, CSV를 함께 비교해 보겠습니다:
| 데이터 포맷 | 레이아웃 구조 | 중첩 데이터 지원 | 스트리밍 읽기/쓰기 | 적합한 활용 시나리오 |
|---|---|---|---|---|
| JSON | 단일 계층 트리 구조, 한 번에 전체 로드 필요 | 네이티브 지원 | 어려움 (전체 파일 로드 필요) | Web API 전송, 설정 파일 |
| CSV | 2D 평면 테이블, 쉼표로 필드 구분 | 어려움 (이스케이프/인코딩 필요) | 네이티브 지원 | Excel 보고서, 평면 데이터 |
| JSONL | 한 줄에 하나의 독립 JSON, 줄바꿈으로 구분 | 네이티브 지원 | 매우 우수 (줄 단위 읽기 및 추가) | AI 학습 데이터셋, 대용량 Log 기록 |
왜 AI 모델 학습과 빅데이터 ETL에서는 JSONL을 선호할까?
최근 OpenAI, Anthropic 등의 대형 언어 모델(LLM)이 부상함에 따라 JSONL은 미세조정(Fine-tuning) 및 데이터셋 준비의 최선책으로 떠올랐습니다. 여기에는 두 가지 핵심 장점이 있습니다:
1. 극도로 낮은 메모리 점유율 (Streaming 스트리밍 처리 지원)
학습 데이터베이스가 50 GB에 달할 때, 기존 JSON 파일 형태라면 프로그램이 50 GB 파일 전체를 메모리에 읽어와 구문 트리를 분석해야 하므로 즉시 메모리 초과(OOM)가 발생합니다.
반면 JSONL은 **줄 단위 스트리밍 읽기(Line-by-line Streaming)**를 지원합니다. 프로그램은 한 번에 한 줄(몇 KB 수준)만 읽어와 처리한 뒤 메모리를 해제하고 다음 줄을 읽어옵니다.
flowchart TD
subgraph TraditionalJSON["기존 JSON 읽기 방식"]
A1["50 GB JSON 파일 읽기"] --> A2["전체 파일 구문 트리 분석"]
A2 --> A3["메모리에 한 번에 50 GB 로드"]
A3 -->|고위험| A4["메모리 초과 다운 (OOM)"]
end
subgraph JSONLStreaming["JSONL 스트리밍 읽기 방식"]
B1["50 GB JSONL 파일 열기"] --> B2["1번째 줄 읽기 (5 KB)"]
B2 --> B3["단일 데이터 분석 및 처리"]
B3 --> B4["메모리 해제 후 다음 줄 읽기"]
B4 --> B5["안정적이고 효율적인 대용량 데이터 처리"]
end
대용량 데이터 처리에 있어 JSONL은 메모리 소비를 O(N)에서 O(1)로 줄여줍니다!
2. 락 없는 무제한 추가 지원 (Append-Only Logging)
분산 시스템이나 로그 수집 환경에서 파일 끝에 데이터를 추가하려는 경우:
- 기존
JSON: 파일 전체를 읽은 뒤 끝부분의]를 제거하고, 쉼표,를 붙인 후 새 데이터를 쓰고 다시]를 붙여야 합니다. - JSONL: 파일 끝에 문자열과 줄바꿈 기호
\n를 직접 추가(append)하기만 하면 쓰기가 완료됩니다.
3. 빅데이터 병렬 처리 (Parallel Processing)
JSONL은 각 줄이 독립된 JSON 객체이므로, 대용량 파일을 임의의 줄바꿈 위치에서 여러 블록으로 분할하여 여러 CPU 코어나 계산 노드로 보내 서로 방해 없이 병렬 연산을 수행할 수 있습니다.
개발자가 알아야 할 JSONL 5가지 엄격한 포맷 규칙
JSONL은 매우 유연하지만, 파서가 원활하게 읽을 수 있도록 공식 사양(jsonlines.org)에서 5가지 엄격한 포맷 제약을 규정하고 있습니다:
규격 상세 설명
| 규격 번호 | 엄격한 규칙 항목 | 설명 및 올바른 예시 |
|---|---|---|
| 규칙 1 | 모든 줄은 유효한 JSON이어야 함 | 각 줄을 독립적으로 추출했을 때 표준 JSON.parse()로 파싱 가능해야 합니다. |
| 규칙 2 | 이스케이프되지 않은 줄바꿈 금지 | 문자열 내에 줄바꿈이 포함된 경우 \n으로 이스케이프해야 하며, 다중 줄 배치는 금지됩니다. |
| 규칙 3 | 최외곽 기호 사용 금지 | 최외곽 대괄호 [] 사용이 엄격히 금지되며, 줄과 줄 사이에 쉼표 ,를 붙여서는 안 됩니다. |
| 규칙 4 | BOM 없는 UTF-8 인코딩 | 엄격하게 UTF-8 인코딩을 사용해야 하며, BOM 헤더를 포함해서는 안 됩니다. |
| 규칙 5 | 기본적으로 빈 줄 미포함 | 모든 줄은 유효한 데이터여야 하며, 파일의 마지막 줄에만 끝 빈 줄이 허용됩니다. |
실전 분석: 안전성이 높은 JSONL 읽기 코드 작성 방법
실제 개발에서 JSONL은 고정 스키마가 없는(Schema-less) 특성을 가지므로, 줄마다 Key가 완전히 다를 수 있습니다. 코드 파싱 시 다음 방어적 원칙을 준수하는 것이 좋습니다:
방어적 코드 예시 (Python)
import json
def process_jsonl_file(file_path):
with open(file_path, "r", encoding="utf-8") as f:
for line_num, line in enumerate(f, 1):
# 1. 빈 줄 자동 건너뛰기 (빈 줄로 인한 파싱 오류 방지)
line = line.strip()
if not line:
continue
try:
data = json.loads(line)
# 2. 방어적 값 가져오기: .get()을 사용하여 KeyError 방지
user_id = data.get("id")
user_name = data.get("name", "Unknown")
# 3. 필드 타입 식별 (다형성 데이터 처리)
doc_type = data.get("type", "default")
print(f"Line {line_num}: [{doc_type}] {user_id} - {user_name}")
except json.JSONDecodeError as e:
print(f"Error parsing line {line_num}: {e}")
# 읽기 실행
process_jsonl_file("dataset.jsonl")
핵심 방어 팁:
strip()으로 양끝 공백을 제거하고, 키에 직접 접근하는 대신.get()을 사용하여 런타임 다운의 90% 이상을 방지하세요!
JSONL, JSON, CSV의 활용 시나리오 선택 가이드
JSONL의 강력한 기능을 확인한 후, 모든 데이터를 JSONL로 바꿔야 할까요? 정답은: 사용 시나리오에 따라 다릅니다!
| 시나리오 요구사항 | 추천 포맷 | 이유 설명 |
|---|---|---|
| Web 프론트엔드/백엔드 API 전송 | JSON | 브라우저 기본 지원이 우수하며, 단일 전송 데이터량이 적절함. |
| 비개발자/마케팅 데이터 내보내기 | CSV | Excel로 직접 열어서 확인 가능. |
| AI 모델 미세조정 (Fine-tuning) | JSONL | OpenAI / Anthropic API 공식 지정 학습 포맷. |
| 시스템 대용량 Log 기록 | JSONL | 쓰기 비용이 낮고, 무제한 추가 및 초저메모리 모니터링 지원. |
| 빅데이터 ETL 파이프라인 | JSONL | 분산 분할 및 병렬 처리가 용이함. |
각 포맷의 특징을 파악하고 올바른 상황에 올바른 도구를 선택하면 데이터 처리 성능을 대폭 향상시킬 수 있습니다!