버퍼(Buffer), 스트림(Stream), 스로틀(Throttle)의 목적과 처리 방식을 실무 예시와 함께 정리

버퍼·스트림·스로틀의 장단점과 사용처를 표와 예시로 정리

실전 코드·아키텍처에서의 적용 팁 포함


  * 결론~

구분  버퍼(Buffer) 스트림(Stream) 스로틀(Throttle)
목적 속도 차이 완충 연속 데이터 처리 처리 빈도 제한
핵심 역할 임시 저장 순차 처리 요청 제어
데이터 저장 O (임시 저장) △ (필요 최소한) X
처리 방식 쌓아두고 처리 들어오는 즉시 처리 일정 시간당 처리 제한
주 사용처 네트워크, I/O, 메시지 큐 대용량 데이터, 실시간 처리 이벤트, API, UI 제어
장점 안정성, 유실 방지 메모리 효율, 실시간성 시스템 보호
단점 메모리 초과 위험 역압(backpressure) 필요 데이터 손실 가능
대표 예시 Kafka, TCP Buffer Node Stream, 파일 다운로드 Scroll Throttle, Rate Limit

 


목차

  1. 버퍼의 개념
  2. 버퍼의 동작 방식
  3. 환경 별 버퍼의 저장 위치
  4. 버퍼에 데이터 유입 시 실제 흐름(네트워크 예시)
  5. 프론트엔드에서의 버퍼 처리

 

버퍼

개념

  • 정의 : 데이터를 일시적으로 저장해 두는 공간
  • 목적 : 처리 속도 차이 완충
  • 위치 : 메인 스레드의 메모리 / Worker 내부 메모리
  • 사용 이유 : 실시간 데이터 폭주 대응
    • 입력은 빠른데 처리가 느린 경우
    • 네트워크 / I/O 지연이 발생하는 경우
    • 데이터 손실 없이 안정적으로 처리해야 하는 경우

버퍼의 본질 “ 어디에 저장 되는가”

  • 추상적인 메모리가 아니라 항상 실제 메모리 공간에 존재함
  • 환경에 따라 위치와 주체가 달라질 뿐
  • 공통 원칙
    • 버퍼 = RAM 상의 메모리 영역
    • 디스크가 아니라 메모리
    • 누가 관리하느냐에 따라 구분

동작 방식

  • 데이터가 들어오면 즉시 버퍼에 저장
  • 소비자는 자신의 처리 속도에 맞춰 버퍼에서 데이터를 꺼냄
  • 버퍼가 가득 차면
    • 대기
    • 오래된 데이터 삭제
    • 에러 발생
    등의 정책 선택
  • 예시
    • 네트워크 패킷 버퍼
    • 파일 I/O 버퍼
    • kafka의 파티션 로그
    • 영상 스트리밍의 미리 로딩 영역

환경 별 버퍼 저장 위치

OS 레벨 버퍼

  • 운영체제가 관리
    • 네트워크 수신 버퍼(TCP Receive Buffer)
    • 파일 읽기/쓰기 버퍼
    • 커널 영역 메모리
  • 특징
    • 애플리케이션은 직접 접근 불가
    • 시스템 콜을 통해서만 사용
    • 매우 빠르지만 크기 제한 존재

런타임 레벨 버퍼

  • JAVA / Node.js 등
  • 언어 런타임이 관리
    • Java: byte[], ByteBuffer
    • Node.js: Buffer, ReadableStream internal buffer
  • 특징
    • 힙 메모리 또는 네이티브 메모리
    • 개발자가 제어 가능
    • GC 또는 런타임 정책 영향 받음

애플리케이션 레벨 버퍼

  • 개발자가 직접 구현
    • 배열
    • Ring Buffer
    • 상태 저장소(Redux, Zustand 등)
  • 특징
    • 가장 많이 쓰임
    • 로직에 맞게 자유롭게 설계 가능
    • 메모리 관리 책임도 개발자에게 있음

데이터 유입 시 실제 흐름 (네트워크 기준)

  • [네트워크] ↓ [OS 네트워크 버퍼] ↓ [런타임 버퍼] ↓ [애플리케이션 버퍼] ↓ [비즈니스 로직 처리]
  • OS 버퍼를 거친다!

프론트 엔드에서의 버퍼 처리

구분 내용

저장 위치 JS Heap (브라우저 메모리)
구현 방식 배열, 큐, 링버퍼
주 사용처 WebSocket, 이벤트, 스트림 처리
초과 정책 삭제, 덮어쓰기, 대기
주의점 메모리 누수, 렌더 성능

배열

const buffer: Message[] = [];

socket.onmessage = (event) => {
  buffer.push(JSON.parse(event.data));
};
  • 가장 단순한 버퍼
  • 메모리 : 브라우저 JS Heap
  • 문제점 : 무한 증가 위험

제한 크기 버퍼 (고정 버퍼)

const MAX_BUFFER_SIZE = 1000;
const buffer: Message[] = [];

function pushBuffer(data: Message) {
  if (buffer.length >= MAX_BUFFER_SIZE) {
    buffer.shift(); // 오래된 데이터 제거
  }
  buffer.push(data);
}
  • 정책
    • 최신 데이터 우선
    • 실시간 UI에 자주 사용

큐 기반 버퍼 (처리용)

const queue: Message[] = [];
let isProcessing = false;

function enqueue(data: Message) {
  queue.push(data);
  process();
}

async function process() {
  if (isProcessing) return;
  isProcessing = true;

  while (queue.length > 0) {
    const item = queue.shift()!;
    await handle(item);
  }

  isProcessing = false;
}
  • 특징
    • 생산자/소비자 모델
    • 서버 데이터 처리, 배치 처리에 적합

WebSocket + 버퍼 + 렌더링 분리

const socketBuffer: Tick[] = [];
let rafId: number;

socket.onmessage = e => {
  socketBuffer.push(JSON.parse(e.data));
};

function render() {
  const data = socketBuffer.splice(0, socketBuffer.length);
  updateChart(data);
  rafId = requestAnimationFrame(render);
}

render();
  • 장점
    • 수신과 렌더 분리
    • 프레임 드랍 방지

브라우저 내부 스트림 버퍼

  • Fetch Stream
    • 브라우저가 내부적으로 버퍼 관리
    • 개발자는 흐름만 소비
  • const response = await fetch(url); const reader = response.body!.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; process(value); // 내부 버퍼에서 chunk 단위 제공 }

상태관리 도구도 버퍼일까

  • Redux 느 RTK Query 모두 서버 응답 결과를 메모리에 캐시함
    • 시간 기준으로 보면 버퍼 + 캐시 의 혼합
    • 버퍼는 일시적으로 사용하고 캐시는 재 사용 목적으로 사용하는 것

+ Recent posts