이벤트 기반 마이크로서비스에 대한 소개 및 가이드를 제공
-
마이크로 서비스
- 비 동기식 이벤트 기반 마이크로서비스
- 장점: 확장성, 느슨한 결합, 테스트 용의성
- 단점: 복잡도, Workflow 추적의 어려움
- 동기식 API 기반 마이크로 서비스
- 장점: 디버깅이 쉬움. 가시성이 높음
- 단점: 서비스 간 의존성이 높음. 경계가 쉽게 무너짐
-
이벤트 기반 마이크로서비스
- 대용량의 데이터를 확장하고 준 실시간 처리를 전제로 이벤트를 생산/소비 하는 패턴을 이용하는 서비스
- Stateful ( 상태 저장), Stateless ( 상태 비 저장 ) 서비스로 분류된다
- 완전한 비동기 방식으로 구현되며 이벤트 브로커를 통해 생산/ 소비 한다
-
통신 구조
- 팀, 시스템이 소통하는 과정에서 의존 관계가 서로 연결된 토폴로지
- 콘웨이 법칙: 시스템 구조는 설계하는 조직의 통신 구조를 그대로 따라간다는 원칙
- 핵심 비즈니스 데이터는 필요로 하는 모든 서비스가 쉽게 획득하고 사용 할 수 있어야 한다
- 종류
- 비즈니스 통신 구조: 팀과 팀, 부서와 팀 등 비즈니스 요건에 따라 연결된 구조. 하기 구현 통신 구조에 영향을 끼친다
- 구현 통신 구조: 도메인 모델에 대해 비즈니스 프로세스, 데이터 구조, 시스템 설계를 정규화한 구조. 모놀리식 어플리케이션이 대표적인 사례
- 데이터 통신 구조: 구현 서비스간 데이터를 주고받는 프로세스 구조. 일반적인 마이크로서비스에서 API를 사용하는 통신이 대표적인 사례
- 이벤트 기반 통신 구조: 데이터의 생산/소유와 소비를 철저히 분리한 이벤트 스트리밍 방식의 프로세스 구조.
- 단일 진실 공급원: 각 이벤트는 사실 진술서(state of fact)로써 존재한다
- 컨슈머 스스로 모델링과 쿼리를 진행한다
-
토폴로지
- 서비스, 이벤트 스트림, API 간의 관계를 표현하는 용어
- 마이크로 서비스 토폴로지: 서비스 내부의 이벤트 기반. 변환/저장/방출 등 이벤트에 기반한 데이터 주도 연산을 정의
- 비즈니스 토폴로지: 서비스를 임의로 그룹핑하여 서비스 사이의 비즈니스 관계를 서술
-
이벤트
- 발생한 사건을 정확하게 나타내기 위한 모든 정보(보안정보는 없을 수도 있다)가 있는 기록물
- 일반적으로 키/값 포맷으로 표현된다. 키는 집계에 사용되나 필수는 아니다
- 이벤트 스트림은 단 하나의 생산자 마이크로 서비스를 가진다
- 컨슈머 랙: 마지막 오프셋과 현재 컨슈머 오프셋과의 차이
- 종류
- 키 없는 이벤트: 하나의 사실을 기술한 이벤트
- 엔티티 이벤트: 유일한 ID가 키로 부여됨. 어느 시점의 엔티티 속성/상태를 표현
- 키 있는 이벤트: 한 파티션 내 데이터의 지역성을 보장하는 용도로 쓰임
- 툼스톤 이벤트: 키 있는 이벤트를 삭제하기 위해 값이 NULL인 이벤트
-
이벤트 데이터 규약
- 주고 받을 데이터 포맷과 그 생성 로직을 정의
- 이벤트 스키마를 적용하여 이벤트에 대한 설명 및 변경/ 진화를 표현하기 위함 → 이 때문에 JSON 방식 보다는 Avro, ProtoBuf 가 선호된다
- 이벤트 트리거, 특정 필드에 대한 설명이 충분히 들어가야 한다
- 중대한 변경(Breaking Change)는 각 소유팀과 충분히 협의하여 변경해야 한다
- 주의 사항
- 공통 라이브러리를 만들지 마라 → 컨슈머가 암묵적인 스키마의 변화를 인지하지 못할 수 있다
- 스트림 당 이벤트는 하나만 있어야 한다 → 타입 매개 변수를 이용한 공통 처리도 안된다
- 문자열을 이용해 숫자값을 저장하는 행위
- 정수를 Boolean으로 대체하는 행위
- 문자열을 ENUM으로 사용하지 마라
- 세마포어나 시그널(커맨드)로 사용하지 마라 → 모든 정보를 담아야 이벤트다
-
기존 시스템에 이벤트 기반 시스템 통합하기
- 교차 도메인 셋을 식별하여 각 이벤트 스트림에 발행하는 마이그레이션 전략
- 이벤트 소싱/싱킹
- 외부 저장소에서 데이터를 읽어들어 이벤트를 발생시키는 것을 소싱
- 이벤트를 구독하여 자체 저장소에 저장하는 과정을 싱킹이라 한다
- 데이터 해방 패턴
- 외부 데이터 저장소에서 데이터를 읽어들어 스트림으로 이벤트를 발행하는 방식
- 카프카 커넥트, 아파치 나이파이 같은 라이브러리가 존재한다
- 데이터 해방 패턴을 구축하는 것에 멈추면 안된다. 이는 중간 과정이다
- 종류
- 쿼리 기반: 데이터 저장소를 쿼리하여 추출. 삭제 데이터는 추적이 불가능하다
- 로그 기반: 데이터 구조의 변경 로그를 가진 저장소에서 로그를 통해 추출
- 테이블 기반(트랜잭션 아웃박스 패턴): 특정 테이블에 데이터를 생성하고, 별도의 프로세스가 이를 읽어 이벤트로 발행한 후 데이터를 삭제하는 방식. 어플리케이션 코드가 변경되어야 한다
- 트리거 기반: 테이블에 트리거를 생성하여 아웃 박스 테이블에 적재하는 방법
-
이벤트 브로커의 기반 처리 방식
- 이벤트를 병합 할 때는 병합된 스트림을 정의하는 새로운 스키마를 정의하라
- 카프카는 컨슈머 그룹 중 첫번째로 등록된 클라이언트에게 파티션 할당 임무를 부여한다
- 코파티션: 이벤트 키, 파티션 알고리즘, 파티션 수가 동일한 이벤트 스트림 집합
- 파티션 할당 알고리즘: 파티션을 컨슈머 인스턴스 전체에 고루 분배하기 위한 알고리즘
- 리밸런스가 일어날 때 재 할당 된 파티션의 수를 줄이는데 목표가 있다
-
에러 이벤트의 처리
- 에러 이벤트를 처리하거나 순서를 보장하기 위해 사용되는 처리 방식
- 타임스탬프: 타임스탬프는 일반적으로 프로듀서가 생산한 시간을 사용하여 처리
- 워터마크: 이벤트 진행 사항을 추적하고 특정 시간 이전까지 데이터 처리가 완료됨을 알기 위해 사용
- 스트림 시간: 카프카 스트림즈에서 사용하는 처리된 이벤트 중 가장 최근의 타임스탬프를 유지하는 방식
- 지각 이벤트 처리
- 이벤트 폐기, 대기, 유예 기간과 같은 방식을 이용한다
- 무한 이벤트 스트림에서는 본질적으로 완벽한 확정성을 달성 할 수 없다