분산 시스템의 메시지 전달 기법과 실패 대응 전략
1. 분산 시스템에서의 통신 실패 시나리오¶
단일 컴퓨터 내의 메서드 호출과 달리, 네트워크로 연결된 분산 시스템에서는 클라이언트가 요청을 보낸 후 응답을 받지 못했을 때 다음과 같은 다양한 가능성이 존재합니다.
- 서버 수신 전 실패: 요청이 서버에 도달하기 전에 네트워크 문제로 유실됨.
- 서버 처리 중 실패: 서버가 요청을 받았으나 작업을 수행하기 직전 혹은 수행 중에 다운됨.
- 응답 전송 중 실패: 서버는 작업을 성공적으로 마쳤으나, 클라이언트로 확답(ACK)을 보내기 직전 네트워크가 끊김.
핵심 문제: 클라이언트 입장에서는 위 세 가지 상황이 모두 '응답 없음'으로 똑같이 보이기 때문에, 서버가 실제로 작업을 수행했는지 알 길이 없습니다.
2. 메시지 전달 방식 (Delivery Guarantees)¶
시스템의 성격에 따라 클라이언트와 서버 간에 미리 약속된 전달 방식을 선택해야 합니다.
① At Most Once (최대 한 번)¶
클라이언트가 요청을 딱 한 번만 보내고, 응답이 없더라도 재시도하지 않는 방식입니다. * 특징: 메시지가 유실될 수 있지만, 중복 실행될 위험은 전혀 없습니다. * 사용 사례: * 로그 및 모니터링: 일부 데이터가 누락되어도 전체 추세에 지장이 없는 경우. * 푸시 알림/광고 메일: 사용자에게 동일한 알림이 여러 번 가서 스팸처럼 느껴지는 것을 방지해야 할 때.
② At Least Once (최소 한 번)¶
클라이언트가 서버로부터 성공 응답을 받을 때까지 계속해서 재시도하는 방식입니다. * 특징: 메시지 유실은 없으나, 서버에서 동일한 작업이 여러 번 수행될 위험이 있습니다. * 전제 조건: 반드시 작업이 멱등성(Idempotency)을 가져야 합니다.
3. 멱등성 (Idempotency)의 이해¶
- 멱등 작업: 여러 번 수행해도 결과가 처음 한 번 수행했을 때와 동일한 작업.
- 예: 파일의 첫 줄 읽기, 사용자 상태를 '활성'으로 변경, 특정 ID의 데이터 삭제.
- 비멱등 작업: 수행할 때마다 시스템 상태가 변하는 작업.
- 예: 파일에 내용 추가, 데이터베이스 값 증가(+1), 계좌 잔액 인출.
4. 비멱등 작업을 멱등하게 만드는 방법 (인공적 멱등성)¶
결제와 같이 중요하지만 비멱등적인 작업은 시퀀스 키(Sequence Key)를 도입하여 멱등성을 강제로 부여할 수 있습니다.
처리 프로세스 (예: 대금 청구)¶
- 키 생성: 주문 서비스가 요청마다 고유하게 증가하는 시퀀스 키를 생성하여 보냅니다.
- 재시도 표시: 재시도 시에는
isRetry = true와 같은 플래그를 함께 전송합니다. - 서버 측 검증:
- DB 키 확인: 서버는 작업 처리 전, 저장된 마지막 시퀀스 키와 요청받은 키를 비교합니다.
- 키가 다를 경우: 이전 처리가 실패했음을 의미하므로 작업을 수행하고 새 키를 기록합니다.
- 키가 같을 경우: 이미 처리가 완료되었으나 응답만 유실된 상황이므로, 추가 작업 없이 성공 응답만 다시 보냅니다.
5. 요약 및 결론¶
분산 시스템에서 완벽하게 "딱 한 번만" 전달하는 것은 매우 어렵거나 불가능에 가깝습니다. 따라서 시스템 설계자는 서비스의 특성에 맞춰 적절한 전략을 선택해야 합니다.
| 방식 | 유실 가능성 | 중복 실행 가능성 | 적합한 상황 |
|---|---|---|---|
| At Most Once | 있음 | 없음 | 로그, 단순 알림 |
| At Least Once | 없음 | 있음 | 멱등성이 보장된 작업 |
| 인공적 멱등성 도입 | 없음 | 없음(논리적) | 결제, 주문 등 중요 비멱등 작업 |
이러한 복잡성을 해결하는 과정은 확장이 용이하고 느슨하게 결합된 분산 시스템을 구축하기 위해 반드시 지불해야 하는 대가입니다.