본문 바로가기
ETC/System Design

[Transactional Outbox] 개요

by devson 2024. 11. 25.

꼭 MSA가 아니더라도 개발팀의 규모에 따라 API 서버가 도메인/서비스 별로 분리되어 개발되는 경우가 있다.

이때 하나의 서비스에서 이벤트 발생 시 다른 서비스에서도 특정 처리가 필요한 상황이 발생하곤 한다.

 

예를 들어 '게시판 기반 커뮤니티' 앱에서 '회원 서비스'와 '게시판 서비스'가 분리되어 있는 경우,

회원 탈퇴 시 해당 회원의 게시물을 삭제/숨김 처리해야하는 경우가 있다.

단순한 개발을 위해 직접적으로 '회원 서비스'가 '게시판 서비스'로 직접 호출을 할 수 있다.

 

이때 만약 어떤 이유로 인해 '회원 서비스'에서 '게시판 서비스'로 호출을 실패하거나

실패 케이스 1

 

'게시판 서비스' 호출을 성공하였으나 그 이후 작업에서 오류가 발생하는 경우가 발생할 수도 있다.

('게시판 서비스'에서만 데이터가 처리되었고 '회원 서비스'에서는 데이터 처리가 되지 않았기 때문에 발생 시 골치 아픈 케이스이다)

실패 케이스 2

 

이러한 문제로 인해 서비스 간의 직접적인 호출은 개발 편의성과 서비스의 안정성 사이의 트레이드 오프 관계를 갖는다.

(소규모의 서비스이거나 조직이라면 서비스간 직접 호출을 하는 경우도 잦으며, 실패 케이스에 대한 오류 알람 설정 및 정합성 처리에 대한 사후 대책이 준비되어 있다면 단순화된 형태로 개발할 수 있다)

 

앞서 살펴본 문제는 서비스 간의 직접적인 결합으로 인해 생길 수 있는 문제로 이러한 문제를 피하기 위해

서비스 간 직접 호출 대신 message queue를 통한 이벤트 전파를 사용하여 서비스 간 데이터 동기화 처리를 할 수 있다.

 

하지만 message queue를 사용한다고 앞서 말한 문제가 없어지는 건 아니다.

직접 호출로 인한 몇몇 문제는 해결해줄지언정 서비스 간 의존도가 그대로 서비스와 message queue와의 의존도로 바뀌기 때문에 이 역시도 서비스 안정성에 해가 되는 포인트이다.

 

이벤트 전파를 안정적으로 하기 위해 제안된 것이 Transactional Outbox pattern 이며 단순하게 서비스 데이터를 쌓는 DB에 이벤트도 같이 쌓음으로써 '서비스에서 데이터 처리'와 '이벤트 발행'의 정합성을 지키는 것이다.

동일한 DB를 사용하기 때문에 동일한 transaction을 사용할 것이며, 서비스 데이터가 업데이트 됨과 동시에 이벤트 데이터가 DB에 쌓이게 될 것이다.

그리고 다른 worker에서 DB에 쌓인 이벤트를 message queue에 발행한다.

https://microservices.io/patterns/data/transactional-outbox.html

(outbox는 이벤트를 담는 '임시 보관함'의 역할을 하기 때문에 outbox라고 명명한 것 같다)

 

Transactional Outbox pattern의 개념은 그다지 어렵지 않다.

하지만 이를 직접 구현할 때는 그 방법이 회사마다 다양하다.

  • microservices.io에 따르면 크게 Polling publisher 방식과 Transaction log tailing 방식이 있다.
  • Polling publisher는 worker가 DB에 쌓인 이벤트를 주기적으로 polling 하여 message queue에 발행하는 방법이다.
    • 이때 이벤트의 (발행 대기, 발행 처리 중, 발행 완료와 같은)발행 상태만 잘 다룬다면 쉽게 구현할 수 있는 방식이다.
    • 반면 주기적으로 polling을 해야하기 때문에 주기에 따라 이벤트 발행이 늦어지거나 너무 잦으면 DB에 부하가 갈 수도 있다.
    • RIDI의 경우 정석적인 Polling publisher 방식을 사용하였다.
    • 29CM의 경우 Polling publisher를 최소화하기 위해 특별한 처리를 추가하였다.
  • Transaction log tailing은 이벤트가 쌓이는 테이블에 대한 transaction log 변경을 감지하여 message queue에 이벤트를 발행하는 방법이다.
    • Debezium과 같은 CDC tool을 사용하는 방식이 잘 알려진 방식이며 DB에 쌓인 이벤트를 빠르고 안정적으로 message queue에 발행할 수 있다.
    • CDC를 사용한다면 추가적인 인프라를 구성해야하기 때문에 구축 비용과 운영 비용이 급격하게 올라간다.

댓글