헬창 개발자

안정적인 재시도 전략: Exponential Backoff + Jitter 본문

공부방

안정적인 재시도 전략: Exponential Backoff + Jitter

찬배 2025. 8. 14. 11:26

분산 시스템에서 API 호출 실패는 흔한 일이다. 그렇지만 무작정 재시도를 반복하는 건 오히려 네트워크 혼잡을 부추긴다.

“3번 재시도를 하더라도 모두 실패로 끝날 가능성이 높다. 게다가, 모든 클라이언트가 한꺼번에 재시도하면 네트워크 트래픽이 최대 3배 증가할 것이다.” Random Access Memories

단순 재시도의 문제점

많은 코드에서 단순하게 이런 재시도를 합니다.

for attempt in range(5):
    try:
        result = call_api()
        break
    except:
        time.sleep(1)  # 무조건 1초 대기

문제는,

  • 요청이 실패하면 모든 클라이언트가 동시에 1초마다 요청
  • 결과적으로 서버에 트래픽 폭탄 발생
  • 실패가 반복되면 복구 속도 지연

1. Exponential Backoff (지수 백오프)

재시도 간격을 지수 함수적으로 늘리는 방식입니다.

  • 예시: 100 ms → 200 ms → 400 ms …
  • 장점: 실패가 반복될수록 재요청 빈도가 줄어 서버 부담 감소

Exponential Backoff: 지수적으로 간격 늘리기

Exponential Backoff는 재시도 간격을 점점 늘리는 방식입니다.

  • 1회차: 1초 대기
  • 2회차: 2초 대기
  • 3회차: 4초 대기
  • 4회차: 8초 대기
import time

base_delay = 1
for attempt in range(1, 6):
    delay = base_delay * (2 ** (attempt - 1))
    print(f"{attempt}회차: {delay}초 대기")
    time.sleep(delay)

이렇게 하면 실패가 계속될수록 서버 요청 빈도가 줄어 부하가 완화됩니다.

하지만 단점도 있습니다.

모든 클라이언트가 동일한 패턴을 따른다면 다시 동시에 몰리는 상황이 발생합니다.


2. Jitter (랜덤 지연)

이런 상황에서 등장하는 개념이 Jitter(지연변이)이다. 원래 Jitter는 데이터 통신 용어로 사용될 때는 패킷 지연이 일정하기 않고, 수시로 변하면서 그 간격이 일정하지 않는 현상을 의미한다. Jitter 개념을 Retry에 이용하면 API를 요청하는 클라이언트 간의 동일한 재시도 시간 간격에 무작위성을 추가하여 서로 요청하는 시간대의 동시성(?)을 분산시킬 수 있다.

Jitter: 랜덤성 추가하기

문제는, 모든 클라이언트가 같은 로직을 쓰면 여전히 같은 타이밍에 재시도를 한다는 점입니다.
이를 방지하기 위해 Jitter(랜덤 지연)를 적용합니다.

import time
import random

base_delay = 1
max_delay = 16

for attempt in range(1, 6):
    delay = min(base_delay * (2 ** (attempt - 1)), max_delay)
    jitter = random.uniform(0, delay * 0.1)  # ±10% 랜덤
    final_delay = delay + jitter
    print(f"{attempt}회차: {final_delay:.2f}초 대기")
    time.sleep(final_delay)

효과:

  • 요청 타이밍이 분산됨
  • 서버가 한 번에 모든 재시도를 처리하지 않아도 됨
  • 전체 성공률 향상
  • Jitter를 추가하면 "동시에 요청 몰림" 문제를 완화할 수 있습니다.
  • 다양한 방식이 존재합니다 (Full, Equal, Decorrelated Jitter 등)

참고자료

https://jungseob86.tistory.com/12

https://aws.amazon.com/ko/blogs/architecture/exponential-backoff-and-jitter/

https://medium.com/@odysseymoon/spring-webflux%EC%97%90%EC%84%9C-error-%EC%B2%98%EB%A6%AC%EC%99%80-retry-%EC%A0%84%EB%9E%B5-a6bd2c024f6f

'공부방' 카테고리의 다른 글

dev 브랜치 기반의 CI/CD 파이프라인 설계  (1) 2025.08.29
Hash Ring  (1) 2025.07.03
Sync/Async & Blocking/Non-blocing  (2) 2025.06.30
종속성 관리 - 서브모듈, 서브트리  (0) 2025.06.17
메시지 브로커(Redis)와 Celery  (0) 2025.05.29