이벤트 기반 아키텍처(EDA)의 정합성
| topics | 300-백엔드개발 |
| types | 이론 |
| tags |
이벤트 기반 아키텍처(EDA)의 정합성
이벤트 기반 아키텍처에서 데이터 정합성을 어떻게 보장할까
정합성 관리 방식
1. 트랜잭셔널 아웃박스 패턴 (Transactional Outbox Pattern)
- 도메인 데이터 변경과 이벤트 발행을 하나의 트랜잭션으로 묶어 처리합니다.
- 예: 주문 생성 시
orders테이블에 데이터를 저장하고, 동시에outbox테이블에 이벤트를 기록합니다[^1][^4][^8]. - 장점: 데이터베이스의 ACID 특성을 활용해 도메인 상태와 이벤트 발행의 원자성을 보장합니다.
- 구현 예시:
BEGIN TRANSACTION;
INSERT INTO orders (...) VALUES (...);
INSERT INTO outbox (event_type, payload) VALUES ('OrderCreated', '...');
COMMIT;
2. 이벤트 발행 보장 메커니즘
- 배치 재시도: 주기적으로
outbox테이블을 스캔하여 미발행된 이벤트를 재발행합니다[^1][^8]. - 이벤트 상태 추적:
public class OutboxEvent {
private boolean published; // 발행 성공 시 true로 업데이트
private LocalDateTime createdAt;
}
- 메시지 브로커의 신뢰성: Kafka, RabbitMQ와 같은 시스템은 메시지 영속화와 재전송 기능을 제공합니다[^6][^7].
3. 사가 패턴 (Saga Pattern)
- 장기 실행 트랜잭션을 이벤트 시퀀스로 분할하고, 실패 시 보상 이벤트를 트리거합니다[^5][^7].
- 예: 결제 실패 →
OrderCancelled이벤트 발행 → 재고 복구 로직 실행.
4. 이벤트 소싱 (Event Sourcing)
- 모든 상태 변경을 변경 불가능한 이벤트로 저장합니다.
- 시스템 상태는 이벤트 재생을 통해 복구되므로, 데이터 정합성을 자연스럽게 보장합니다[^5].
이벤트 큐의 지속성
이벤트 큐는 다음과 같은 방식으로 유지됩니다:
| 특성 | 설명 |
|---|---|
| 영속적 저장소 | Kafka, AWS SNS/SQS 등 메시지 브로커가 이벤트를 디스크에 저장합니다[^3][^6]. |
| 재시도 로직 | 소비자 측에서 메시지 처리 실패 시 재시도 큐로 이동시킵니다[^7]. |
| 이벤트 재생 | 특정 시점부터 이벤트를 재처리하여 시스템 상태를 복구할 수 있습니다[^5]. |
주요 도전 과제와 해결 방안
1. 중복 처리 방지
- Idempotent Consumer: 동일 이벤트의 중복 실행을 방지하기 위해 이벤트 ID를 기반으로 처리 여부를 검증합니다[^4].
if (!eventLogRepository.existsByEventId(event.getId())) {
processEvent(event);
eventLogRepository.save(new EventLog(event.getId()));
}
2. 장애 복구
- Dead Letter Queue (DLQ): 최대 재시도 후 실패한 이벤트를 별도 큐로 이동시켜 수동 조치가 가능하게 합니다[^7].
3. 성능 최적화
- 이벤트 축소: 페이로드를 최소화하여
식별자 + 이벤트 유형 + 타임스탬프만 포함시킵니다[^2][^6].
{
"eventType": "OrderCreated",
"orderId": "ORD-123",
"timestamp": "2025-06-10T17:00:00"
}
결론
이벤트 기반 아키텍처는 트랜잭셔널 아웃박스 패턴과 메시지 브로커의 영속성을 통해 정합성을 관리하며, 이벤트 큐는 디스크 저장과 재시도 메커니즘으로 지속성을 보장합니다. 다만, 복잡한 비즈니스 시나리오에서는 사가 패턴이나 이벤트 소싱과의 조합이 필수적입니다.