본문 바로가기
Architecture

[Architecture] 4가지 유형의 Event Driven Architecture

by gungle 2023. 9. 11.

Event Driven Architecture Pattern에서 Event Driven은 IT 영역에서 오래 사용된 키워드이며, 현재도 그 영향력이 대단하여 2018년 Gartner에서 선정한 유망한 기술 트렌드 중 하나로 뽑히기도 했다. Event Driven이라는 용어는 programming, architecture와 연결되어 다양한 정의로 표현된다. 주로 Event Driven 시스템은 Message Broker(Kafka, Rabbit MQ, Redis)와 결합하여, Message Driven 시스템으로 구성된다. 하지만, Event Driven Architecture Pattern이 때로는 불필요한 복잡성을 높이는 결과만 초래할 수 있으며, 그렇기에 더욱 신중하게 고려해야 한다.

 

Top 10 Strategic Technology Trends for 2018: Event-Driven Model

Digital business is event-driven, so organizations need to invest in event-centric design practices and technologies to exploit digital business moments. Enterprise architecture and technology innovation leaders must champion event thinking across business

www.gartner.com

 

What is Event Driven Architecture?

Event Driven Architecture는 프로그램 실행의 흐름이 이벤트에 의해 결정되는 아키텍처이다.

하지만 한줄의 정의만큼 간단하지 않다. "Devil is in the details(악마는 더 자세한 부분에 있다)"라는 말처럼 매우 복잡한 패턴이 간단한 한줄의 정의로 단순화되어 있다고 생각하는 것이 더 바람직하다.

 

1. (Event) Notification Pattern

가장 간단한 패턴인 Notification Pattern은 이미 지정된 특정 도메인 내에서 변화가 일어나면 발신자(Customer)는 Event Bus에 알림을 보내고, 이 이벤트에 관심이 있는 서비스(Notification Service)는 데이터를 얻기 위해 요청을 보낸다.

이건 실제 서비스의 로직과 분리하여 매우 쉽게 구현할 수 있는 장점이 있다. 그리고 많은 상태를 전달하지 않고 기본에 충실한 데이터만 포함하고 있기 때문에 가볍다. 하지만 그렇다고해서 이 패턴을 과하게 남용한다면 너무 많이 분산되어 있게 될 것이며, 이는 실시간 서비스에서 이벤트의 흐름을 제대로 모니터링하지 않는 한 무슨 일이 일어나는지 더욱 알기 어렵게 된다.

예를 들어 어떤 물류 배송 프로세스가 있다고 가정했을 때, 특정 주문에 대해 이벤트 기반의 패턴을 사용하지 않고 프로세스를 구현한다면 매번 배송과 관련된 API를 호출해야 할 것이다. 이는 곧 해당 애플리케이션(주문)이 배송 프로세스에 종속되는 것을 의미한다. 하지만 아래와 같이

{
  "orderId" : "0bfaab92-504a-4ec1-8c88-0b6df1bf8355"
}

Event Notification 패턴을 따른다면, 주문이 완료된 이후에 해당 내용을 확인할 수 있는 고유 ID만 전달되고, 배송 프로세스가 해당 이벤트를 수신한다면, 배송과 관련된 프로세스가 주문에 종속되지 않을 수 있고, 또 다른 새로운 주문 시스템에 대해 쉽게 통합할 수 있을 것이다.

하지만, 해당 예시에서 이 패턴으로 게시된 이벤트를 통해 할 수 있는 것은 상당히 제약적일 수 있다. 가령, 배송 서비스에 추가 데이터가 필요한 경우엔 주문 서비스에 재요청을 보내야 하며, 이벤트가 게시된 서비스에서 항상 API를 호출해야 할 것이다.

 

2. Event Carried State Transfer Pattern (ECST)

이름에서 알 수 있듯이, Event Carried State Transfer Pattern(이벤트 전달 상태 전송 패턴)의 주요 특징은 이벤트가 상태를 포함한다는 것인데, 이는 생산자로부터 상태를 검색하기 위한 식별자를 포함하는 알림 이벤트와는 차이가 있다. 주문하는 고객을 위한 상태 저장 이벤트는 다음과 같다.

{
  "orderId" : "0bfaab92-504a-4ec1-8c88-0b6df1bf8355",
  "customerId" : "77bdf5e5-2bcb-43a9-978c-6ae90d6a08db",
  "items" : [ {
    "name" : "Vintage Yamaha FG 180 Red Label Guitar",
    "quantity" : 1,
    "price" : 560
  } ]
}

ECST 패턴을 활용한다면 위의 예시와 같이 이벤트 상태의 복사본을 유지하기 때문에 서비스 간의 상호 작용을 완전히 제거할 수 있다. 이를 통해 Decoupling(비동조화)과 High Availability(고가용성)이라는 장점을 얻을 수 있는데, 이는 주문 서비스가 필요한 모든 고객 데이터가 배송 프로세스에도 존재하기 때문에, 고객 정보와 관련된 서비스가 없어도 동작할 수 있다는 것이다. 하지만 데이터의 중복(Data Duplication)과 같은 문제나, 고객 정보와 관련된 서비스와 배송과 관련된 프로세스 상에 데이터 일관성을 유지하기 위한 문제가 생길 수 있다. 이 문제는 일반적인 분산 처리 시스템에서 가용성과 일관성을 동시에 달성할 수 없는 문제(*CAP theorem)로 해석할 수 있다.

*CAP 정리 또는 브루어(Brewer)의 정리는 다음과 같은 세 가지 조건을 모두 만족하는 분산 컴퓨터 시스템이 존재하지 않음을 증명한 정리이다.
- 일관성(Consistency): 모든 노드가 같은 순간에 같은 데이터를 볼 수 있음
- 가용성(Availability): 모든 요청이 성공 또는 실패 결과를 반환할 수 있음
- 분할내성(Partition tolerance): 메시지 전달이 실패하거나 시스템 일부가 망가져도 시스템이 계속 동작할 수 있음

결국 ECST 패턴의 가장 명확한 장점은 다운스트림 시스템에서 필요한 정보를 검색하는 데 있어서 업스트림 시스템에 의존하지 않기 때문에 탄력성(Resilience)과 대기 시간 감소라고 할 수 있다.

 

3. Command Query Responsibility Segregation (CQRS)

CQRS는 이름에서 알 수 있듯이 데이터 저장소의 읽기 및 쓰기 작업을 분리하는 패턴이다. 명령 쿼리를 분리시켜 읽기와 쓰기를 위한 별도의 서비스를 통해 구현한다는 것인데, 특정 작업을 수행하는 모든 메서드들이 특정 작업을 수행하도록 지시하거나, 호출자에게 데이터를 반환하는 형식의 쿼리로 구분되어 있어야 한다. 보다 구체적으로, 해당 매서드가 명백히 사이드 이펙트가 발생하지 않는 경우에만 값을 반환해야 한다. 다시 정리하자면,

  • 명령은 데이터 중심이 아닌 작업 기반이어야 한다. ("ReservationStatus를 예약됨으로 설정"이 아닌 "호텔 객실 예약").
  • 명령은 동기적으로 처리되지 않고 비동기 처리를 위해 큐에 배치될 수 있다.
  • 쿼리는 데이터베이스를 수정하지 않습니다. 쿼리는 도메인 정보를 캡슐화하지 않는 DTO(Data Transfer Object)를 반환한다.

Command 측면에서는 주로 데이터의 일관성을 보장하기 위한 업데이트 요청을 처리하고, 대부분의 시스템에서 Command 쪽은 상대적으로 읽고 질의를 요청하는 측면보다는 낮은 양의 데이터를 처리하기 때문에 비교적 확장에 대한 비용이 그리 높지 않다.

Read(Query) 측면에서는 읽기 성능의 최적화, 비관계형 데이터베이스를 사용하거나, 관계형 데이터 베이스에 정규화작업을 거친 뒤에 데이터를 불러와 저장하는 방식이 되어야 하기 때문에, 확장에 대한 비용이 상대적으로 높다고 할 수 있다.

이후 별도의 읽기 및 쓰기 데이터베이스를 사용하는 경우 동기화된 상태로 유지되어야 한다. 일반적으로 이 작업은 쓰기 모델이 데이터베이스를 업데이트할 때마다 이벤트를 게시하게 하여 수행된다.

이 패턴은 읽기와 쓰기 작업이 병렬로 실행되는 전통적인 접근 방식이 특히 부하가 높은 경우에 많은 논쟁점을 야기할 수 있지만, 두 가지의 작업이 분리되어 복잡도는 높아질 수 있지만, 더 나은 확장성과 탄력성을 보장 받을 수 있다.

 

4. Event Sourcing Pattern

Event Sourcing(이벤트 소싱) 패턴은 4가지 패턴 중 가장 복잡한 패턴이다. 이 패턴의 핵심 아이디어는 상태 변경이 있을 때마다 상태 자체를 업데이트하는 대신 상태 변경을 기록한다는 것이며, 애플리케이션의 상태를 이벤트 시퀀스로 저장하게 된다. 가장 이해하기 쉬운 예시로는 은행 계좌를 예로 들 수 있는데, 은행 계좌의 현재 잔액을 표시하는 것은 테이블의 특정 열의 값이 아니라 과거부터 현재까지의 모든 거래의 합을 나타내는 것을 의미한다. 즉 ES 패턴은 *SSOT(Single Source of Truth)라고 할 수 있다.

*단일 진실 공급원(SSOT; Single Source Of Truth)
- 단일 진실 공급원(SSOT)은 정보 시스템 설계 및 이론중 하나로 정보와 스키마를 오직 하나의 출처에서만 생성 또는 편집하도록 하는 방법론
- 단일 출처를 통해 데이터를 생성하고 편집하고 접근하므로 데이터의 정합성을 지키고 잘못된 데이터 유통을 방지하고 모두가 동일한 데이터를 참조

이 패턴은 이벤트 저장소에 모든 변경 사항이 기록되어 있기 때문에, 변화에 대한 추적 관리 및 보고에 유용하다. 그리고 다운스트림 시스템이 실패할 경우에도, 해당 상태가 이벤트로부터 다시 복구될 수 있기 때문에 안정성이 높으며, ES 패턴에선 각 상태 변경에 대한 레코드만 추가되기 때문에 쓰기 성능에 대해서도 최적화되어 있다.

하지만, 각 이벤트 마다 발생되는 변경 사항에 대해 새로운 데이터가 저장되기 때문에 데이터 저장소의 크기는 기존 접근 방법들에 비해 기하급수적으로 증가할 수 있으며, 이벤트 저장소는 영구적으로 종속되어야 하는 정보의 원천이므로 이벤트 데이터가 업데이트되면 안 된다. 변경 내용을 취소하기 위해 엔터티를 업데이트하는 유일한 방법은 이벤트 저장소에 보정 이벤트를 추가하는 것이며, (데이터가 아닌)연속성을 가진 이벤트을 변경해야 하는 경우, 마이그레이션 중에 저장소의 기존 이벤트를 새 버전과 결합하기 어려울 수 있다. 이를 위해서 새로운 형식을 준수하도록 모든 이벤트를 반복해서 변경하거나 새 형식을 사용하는 새 이벤트를 추가해야 할 수도 있다.

즉, 해당 패턴이 사용되기 적합한 경우는,

  • 데이터에 의도, 목적 또는 이유를 캡처하려는 경우(예를 들어 고객 엔터티에 대한 변경 내용은 이동한 페이지 추적, 폐쇄된 계정 또는 탈퇴와 같은 일련의 특정 이벤트 유형을 추적)
  • 데이터 업데이트 충돌 발생을 최소화하거나 완전히 방지하는 것이 중요한 경우
  • 발생하는 이벤트를 기록하고 재생하여 시스템 상태를 복원하거나, 변경 내용을 롤백하거나, 기록 및 감사 로그를 유지하려는 경
  • 이벤트 사용이 애플리케이션 작업의 자연 기능이고 추가 개발 또는 구현 노력이 거의 필요하지 않은 경우
  • CQRS와 함께 사용 시 읽기 모델이 업데이트되는 동안 결과적 일관성이 허용되거나 이벤트 스트림에서 엔터티와 데이터를 리하이드레이션할 때의 성능 영향이 허용되는 경우

에 적합하며, 반대로 아래와 같은 경우에서는 기피해야 하는 패턴이다.

  • 데이터 뷰에 대한 일관성 및 실시간 업데이트가 필요한 시스템
  • 감사 추적, 기록, 작업 롤백 및 재생 기능이 필요하지 않은 시스템
  • 기본 데이터에 대한 업데이트 충돌 발생이 매우 적은 시스템(예를 들어 데이터를 업데이트하지 않고 주로 추가 작업만 일어나는 시스템)

 

Conclusion

위에서 설명한 것처럼 이벤트 기반의 아키텍처는 현대의 시스템에서 많은 문제를 해결할 수 있고, 꽤 오래전부터 존재해온 아키텍처이다. 하지만 구현을 위해서는 각 서비스 사례마다 적절한 패턴을 심사숙고해서 결정할 필요가 있다.

 


Reference

Event Driven Architecture - Javed Afroz (Medium, 2022-02-16)

Event Driven Patterns - Kasun Sameera (Medium, 2019-12-01)

이벤트 기반 아키텍처 스타일 (Microsoft 기술 문서)

CQRS 패턴 (Microsoft 기술 문서)

이벤트 소싱 패턴 (Microsoft 기술 문서)