dev.Log
backpressure vs RingBuffer 본문
비동기 로그 개발할 때 처음에 백프레셔 방식으로 개발 했었는데 (일단 빨리 개발해보고 증명하고 고도화하는게 목적이라서 큐가 꽉차면 안담도록했다.. )
프레임워크 로그까지 레벨을 낮추니까 큐가 꽉차서 최근 로그가 버려지는 것보다는 오래된 로그를 버리는 게 맞을 것 같아서 링버퍼 방식으로 변경했다.
✅ Backpressure vs RingBuffer 정리
Backpressure | RingBuffer | |
개념 | 데이터 속도를 조절하는 흐름 제어 방식 | 고정된 크기의 원형 버퍼 사용 |
목적 | 소비자가 감당할 수 있도록 생산 속도를 조절 | 낮은 지연시간(High-throughput) 데이터 처리 |
사용 환경 | 비동기 스트림 (RxJava, Reactor, Kafka 등) | 고성능 멀티스레딩 환경 (Disruptor, Kafka 등) |
장점 | 메모리 과부하 방지, OOM 예방 | 고속 처리, 락 없는 데이터 처리 가능 |
단점 | 소비자가 너무 느리면 지연 발생 가능 | 버퍼가 가득 차면 덮어쓰기(데이터 손실 가능) |
대표 기술 | RxJava, Project Reactor, Akka Streams | LMAX Disruptor, Kafka, Netty |
Backpressure는 시스템의 입력 속도가 출력 속도보다 클 때 발생하는 현상으로, 시스템이 과부하 상태에 이를 수 있는 문제를 방지하고 처리 능력을 조정하기 위해 사용됩니다. 주로 데이터 스트림 처리, 네트워크 통신, 또는 리액티브 프로그래밍에서 중요한 개념으로 다뤄집니다.
1. Backpressure (백프레셔)
"생산자가 너무 많은 데이터를 보내면, 소비자가 감당할 수 있도록 속도를 조절하는 기법"
- 발생 이유: 데이터를 처리하는 소비자(Consumer)의 처리 속도가 데이터 생산자(Producer)의 생성 속도를 따라잡지 못할 때 발생.
- 문제점: 처리되지 않은 데이터가 계속 쌓이면 메모리 부족, 성능 저하, 애플리케이션 충돌 등의 문제가 발생할 수 있음.
2. Backpressure를 처리하는 방법
1) 버퍼링 (Buffering)
- 데이터를 임시로 저장할 버퍼를 사용하여 소비자가 데이터를 처리할 시간을 벌어줌.
- 제한된 크기의 버퍼를 사용하는 것이 일반적이며, 버퍼가 꽉 차면 추가 조치를 취함.
- 단점: 버퍼 크기가 작으면 데이터를 손실할 위험이 있고, 크면 메모리 낭비가 발생.
2) 드롭/샘플링 (Dropping/Sampling)
- 특정 조건에서 일부 데이터를 버림.
- 사용 예: 네트워크 패킷 손실, 비디오 스트리밍에서 프레임 드롭.
- 샘플링은 데이터의 하위 집합을 선택하여 중요 정보를 유지하면서 처리 부하를 줄임.
3) 속도 조정 (Throttling)
- 생산자가 데이터를 생성하는 속도를 줄임.
- 소비자가 데이터를 처리하는 속도와 생산자의 속도를 동기화.
- 장점: 메모리 낭비를 방지하고 안정적 동작 보장.
4) 배압 신호 (Backpressure Signals)
- 소비자가 생산자에게 "데이터를 천천히 보내라"는 신호를 보내 조정.
- 주로 리액티브 스트림(Reactive Streams)에서 사용됨.
5) 데이터 윈도잉 (Windowing)
- 데이터를 일정 시간 또는 크기로 나누어 처리.
- 예: RxJava의 window 연산자.
3. 적용 사례
- 리액티브 프로그래밍 (Reactive Programming):
- RxJava, Project Reactor 등에서 Flowable, Publisher, Subscriber를 통해 배압을 제어.
- 예: onBackpressureBuffer, onBackpressureDrop 연산자를 사용.
- 네트워크 통신:
- TCP/IP 프로토콜의 슬라이딩 윈도우(Sliding Window)는 배압의 한 예.
- 송신자는 수신자가 처리할 수 있는 데이터만 보냄.
- 메시지 큐 (Message Queue):
- Kafka, RabbitMQ에서 소비자의 처리 속도를 조정.
4. Spring WebFlux에서의 Backpressure
Spring WebFlux는 리액티브 스트림을 기반으로 작동하며, 배압을 기본적으로 지원합니다.
- Publisher와 Subscriber 간의 데이터 흐름 제어:
- Publisher가 Request를 통해 데이터를 필요한 만큼만 생성.
- Flux나 Mono로 구성된 데이터 스트림에서 쉽게 구현 가능.
java
코드 복사
Flux.range(1, 1000) .onBackpressureBuffer(10) // 버퍼 크기를 제한 .subscribe(data -> { // 소비자가 처리하는 로직 System.out.println(data); });
5. 핵심 요약
- Backpressure는 데이터 처리 속도 불균형을 해결하기 위한 메커니즘.
- 버퍼링, 드롭, 속도 조정, 배압 신호 등을 활용해 문제를 완화.
- 리액티브 스트림 및 네트워크 통신에서 중요한 역할.
'BACKEND.* > Server' 카테고리의 다른 글
epoll 보다 좋은 io_uring (0) | 2025.02.01 |
---|---|
멀티마스터에서 키충돌 피하는 법 (0) | 2024.12.28 |
JIT 컴파일러 (0) | 2024.12.22 |
하이퍼스레딩 (0) | 2024.12.22 |
Perf C2C (2) | 2024.12.15 |
Comments