백프레셔(Backpressure)란? 시스템이 과부하를 스스로 조절하는 법

백프레셔란 무엇인가

백프레셔(Backpressure)는 데이터를 생산하는 쪽(Producer)과 소비하는 쪽(Consumer)의 처리 속도 차이로 인해 시스템에 과부하가 걸릴 때, 소비자가 생산자에게 ‘천천히 보내달라’는 신호를 보내 흐름을 조절하는 메커니즘입니다. 쉽게 말해 수도관에 비유할 수 있습니다. 수도꼭지(생산자)에서 물을 계속 틀어놓는데 배수구(소비자)가 물을 처리하는 속도가 느리면 결국 물이 넘쳐 흐르게 됩니다. 백프레셔는 이때 수도꼭지 쪽에 신호를 보내 물의 양을 줄이거나 잠그도록 하는 역할을 합니다.

소프트웨어 시스템에서도 마찬가지입니다. API 서버, 메시지 큐, 스트리밍 파이프라인 등에서 요청이나 데이터가 처리 속도보다 빠르게 들어오면 메모리 부족, 응답 지연, 서비스 다운 같은 문제가 발생합니다. 백프레셔는 이런 상황을 방지하기 위해 시스템이 스스로 유입량을 제어하도록 설계하는 개념입니다.

동작 원리와 대표적인 예시

백프레셔를 구현하는 방식은 크게 몇 가지로 나뉩니다.

  • 버퍼링: 일정량의 데이터를 큐에 쌓아두고 처리 속도에 맞춰 꺼내 쓰는 방식
  • 드롭(Drop): 처리 한계를 넘으면 초과된 데이터를 버리는 방식
  • 블로킹(Blocking): 생산자가 소비자의 처리 속도에 맞춰 대기하도록 만드는 방식
  • 신호 기반 제어: 소비자가 ‘더 보낼 수 있다’ 혹은 ‘멈춰달라’는 신호를 명시적으로 전달하는 방식

대표적인 예로 Java의 리액티브 스트림즈(Reactive Streams) 스펙에서는 Subscriber가 request(n) 메서드를 통해 자신이 처리할 수 있는 만큼만 데이터를 요청합니다. Publisher는 요청받은 개수만큼만 데이터를 전달하기 때문에 Subscriber가 감당하지 못할 양의 데이터가 한꺼번에 몰리는 일이 없습니다. TCP 프로토콜의 흐름 제어(Flow Control)도 유사한 원리로, 수신 측 버퍼 상태에 따라 송신 측의 전송 속도를 조절합니다.

실무에서 왜 필요한가

백프레셔가 없는 시스템은 트래픽이 몰릴 때 매우 취약합니다. 예를 들어 대량의 로그 데이터를 처리하는 파이프라인에서 컨슈머가 처리 속도를 따라가지 못하면 메모리에 데이터가 계속 쌓이다가 결국 OOM(Out Of Memory) 에러로 서버 전체가 죽는 상황이 발생할 수 있습니다.

Kafka, RabbitMQ 같은 메시지 브로커나 Node.js의 스트림 API, RxJS, Project Reactor 같은 라이브러리들은 백프레셔 처리를 기본적으로 지원하여 개발자가 직접 유량 제어 로직을 짜지 않아도 안정적인 데이터 흐름을 만들 수 있게 도와줍니다. 결국 백프레셔는 시스템이 스스로의 한계를 인지하고, 무너지지 않는 선에서 최대한의 성능을 유지하도록 만드는 안전장치라고 할 수 있습니다.

관련 글

댓글 남기기