배경을 알아보자.

비즈니스 수요가 증가함에 따라 기능의 종류는 다양해지고 요구량이 증가하였으며, 결과적으로 서비스의 크기는 거대해졌다. 여러 한계에 봉착하게 된다. 

(1) 서비스의 수정 / 업데이트 속도가 느려진다. 

수정된 부분이 극히 일부이더라도, 전체 서비스를 다시 빌드 및 배포해야하므로 시간이 과대하게 소요된다.

(2) 작은 장애가 전체 장애로 이어진다.

마찬가지로 장애가 발생한 부분이 일부이더라도, 그 외 기능과 분리되어있지 않으므로 전체 장애로 연결된다.

(3) Scale out의 부담이 증가한다.

실제 자원 증설이 필요한 서비스는 일부임에도, 전체를 단위로 증설이 발생.

 

서비스가 너무 커서 생긴 문제들이라면, 줄이는 것이 해결 방향 아닐까? 라는 접근으로 하나의 거대해진 서비스를, 여러 개의 작은 서비스로 치환한 것이 MSA.

→ 일부만 수정해도 운영 환경에 반영되고, 일부의 장애가 전체로 확산되지 않도록 관리할 수 있고, 자원 증설의 단위를 축소시킬 수 있을 것.

 

그런데 이로 인해서 발생하는 여러 이슈가 있다. 

하나의 서비스를 타겟했던 수많은 기능들이 분산된 각각의 서비스에 대해서도 일일이 다 제공되어야 하는, 노고의 수평적/양적 증가.

분산된 서비스가 어딘지 알고 접근하지? / 통신도 많아지는데 어떻게 다 모니터링하지?

빌드, 배포는 언제 다 하지?

서비스 종류가 너무 다양한데?

성능이 저하되는 것 같은데?

TCP 통신을 써야되나?

 

DB까지도 나눠져야 했던 이유는. 만약 여러 서비스에 대해서 통합 DB를 사용한다면, 해당 DB 서버에 문제가 발생하면, 나눈 서비스 모두 데이터에 접근이 불가해진다. 

이럴 경우 독립적인 기능 간 의존성을 낮추자는 MSA의 장점이 퇴색되므로 Micro화 대상에는 DB도 포함되는 것. 

 

기능별로 서비스도 DB도 나누고보니 데이터가 분산되었다.

ex. 은행을 예로 들면, 사용자 DB와 계좌 정보 DB가 별개일 때, 특정 계좌를 가진 사용자의 주소를 파악하고 싶은 상황.

→ 분산데이터 조회가 필요해졌다.

방법

(1) DB link

(2) API Composition

(3) 이벤트소싱 + CQRS

하지만 DB link - lock in  발생

API Composition - 복잡한 쿼리에 부적합하다. 여러 서비스에 대해서 복잡도 높은 요청을 보내야할 수도 있기 때문. → 요청 별로 네트워크 비용 발생 → 성능 저하

→ 그래서 이벤트 소싱이 필요해졌다.

 

이벤트소싱 & CQRS 라는 개념이 이미 있었음

다만 초창기에 통 DB에 대해서 백엔드만 모델을 Command, Query model로 각각 나누는 것보다 복잡한 구조에 녹여내야 할 필요성 생김.

https://martinfowler.com/bliki/CQRS.html#:~:text=CQRS%20stands%20for%20Command%20Query,you%20use%20to%20read%20information.

이벤트 소싱 패턴 한 문장으로: 

"Capture all changes to an application state as a sequence of events." - Martin Fowler

 

 

전통적인 데이터 저장 방법은 Table을 두어 row 별로 업데이트하는 것

이 경우에는 비즈니스가 확장될 수록, 이력(audit)테이블이 너무 많아진다.

 

이에 대한 이벤트로 구현하는 경우, 이벤트는 (1) 변경이 불가능하고, (2) Append 방식으로 구현된다.

이벤트는 식별자, 타입, 버전, 발생시간, 내용으로 구성된다.

모든 Event는 순서대로 영구 저장소에 저장하게 된다.

발생한 이벤트는 이벤트 스토어에 보관된다. 

 

이벤트 스토어는 도메인 객체(Aggregate)의 값을 적용할 수 있는 이벤트 핸들러. 

발생한 이벤트의 값을 저장하는 것.

조회한 이벤트 객체를 핸들러를이용하게여 조회하게 되면

이벤트를 순차적으로 도메인 객체의 최신 상태를 알기 위해서는 이벤트 리플레이를 해야 한다.

매번. → 이는 매우 문제

ex. 10000개 이상의 이벤트가 저장되어 있으면, 10000개 이상의 이벤트를 replay해야 한다

 

Snapshot 탄생.(replay된 이벤트 정보0

이벤트시에 적용된 마지막 버전, 리플레이된 도메인 객체

이벤트 저장시 생성.

시간, 이벤트 발생 개수를 기준으로 생성.

 

Event store와 분리된 저장소에 저장 / in-memory

그렇다고 성능문제가 전부 해결되지는 않을 것.

그렇다 해도 100만개 계좌를 대상으로 한다면.. 늦을 것.

 

CQRS

명령과 조회의 책임을 분리하는 것. 

Commands, write, 상태 변경 / queries, read, 데이터 조회

복잡도 줄이고자 만들어짐.

사실상 필수이다.

 

command model과 query 상태 변경 / 이벤트 조회 분리 

Command side에 이벤트가 발생 → 이벤트 스토어로 저장 → event projection (이벤트 스토어에서 쿼리 사이드 db로 이벤ㅌ ㅡ업데이트)

이런 방식을 사용하면, read할 때마다 일일이 write내역을 모두 확인하지 않더라도 이미 업데이트되어있는 최신 상태로부터 빠르게 read할 수 있다.

 

이벤트 소싱?

"어플리케이션의 모든 상태 변화를 순서에 다라 이벤트로 보관한다."

Capture all changes to an application state as a sequence of events

왜 하는지?

데이터 저장방식의 새로운 pattern.

고객에게 제품을 제공하기 위한 과정.(SCM. 공급망 관리 시스템)..

서비스-독립적으로 실행 가능한 어플리케이션.

1개 이상의 서비스와 데이터베이스와 메세징 시스템 등의 공유인프라를 묶어서 시스템이라고 부르기로 함

 

사용자 서비스 / 백 오피스로 구성된 모놀리식. 

문제:주문량이 성장함에 따라서 자동화된 시스템 기반 업무로 전환이 필요했다.

엑셀을 많이 다뤘던 시기. 사람의 손으로 일일이 모놀리틱 시스템 기반으로 다뤘기 때문에 시간이 오래걸렸다!