ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • EDA ( Event - Driven -Architecture)
    DESIGN PATTERN & ARCHITECTURE 2022. 9. 29. 22:37

     

     

     

    최근 아키텍쳐에 관한 강의를 듣고 EDA에 대해 희미하게 나마 생각해보다가,

    동기분 께서 설명해주신 부분을 듣고 공부하면 좋을 것 같아 작성하게 되었다! 🙌

    면접 준비를 하면서 Monolithic Architecture나 MicroService Architecture에 대해서는 공부했지만 

    EDA 부분은 자세히 알지 못했기 때문에 영상을 찾아보았고,

    사진 부분은 모두 유튜브 설명 영상 내용을 캡쳐하였다. 

     

     

     

     

     

     

    Reference 영상 

     

     

     

     

     

    기존의 Monolithic Architecture

     

     

     

     

     

    MSA (Micro Service Architecture)

    • 도커위에 각각의 서비스에 대한 쿠버네티스 pod을 올리고 각각 health check를 하며 통신
    • 데이터에 접근하거나 api 서비스로부터 정보를 받아오는 것이 synchronized하게 발생
    • Ask → wait 패턴 (다른 api의 응답을 기다리며 서로 의존적인 모습)
    • 아무리 작은 MSA로 구성하더라도 서버가 다운되면 정보의 손실 발생 가능성

     

     

     

     

     

    -SAGA 패턴

    • 기존의 monolithic 구조에서는 구매에 대한 여러가지 반응들이 하나의 트랜잭션 안에서 발생하고 하나의 DB에 반영되어 DBMS의 트랜잭션 기능을 통해 commit 혹은 rollback이 일관성있게 관리
    • Applcation 과 DB가 분산된 MSA에서는 트랜잭션 처리를 단일 DBMS에서 제공하는 방식으로 해결이 불가
    • 대안 1) Two-Phase Commit
      • prepare phase와 commit phase를 나눔
      • prepare phase 단계
        • transaction co-ordinator → request-to-prepare 요청 → resource managers
        • transaction co-ordinator ← prepared 응답 ← resource managers
      • commit phase 단계
        • transaction co-ordinator → commit 요청 → resource managers
        • transaction co-ordinator ← done 응답 ← resource managers
      • 하나의 서비스가 장애가 있는 경우나 동시에 각각의 서비스에 락킹이 걸리면 성능의 문제가 발생하여 비효율적
      • 각각의 서비스가 다른 인스턴스에 존재하여 통제에 어려움

     

     

     

     

     

    • 대안 2) SAGA 패턴
      • MS 끼리 이벤트를 주고받아 하나의 MS에서 작업이 실패하면 이전의 MS들에게 보상(compensation)이벤트를 주어 분산환경에서도 원자성 보장
      • 트랜잭션의 관리 주체가 DBMS가 아닌 Application에 존재하며 각각의 어플리케이션은 각각의 DB에 로컬 트랜잭션만을 담당하여 보상 처리를 어플리케이션이 구현
      • 마지막 트랜잭션까지 처리 완료되어 영속화 되면 최종 일관성(eventually consistency) 달성
      • Orchestration 방식과 Choreography 방식이 존재

     

     

    — SAGA - 1) Orchestation 방식

    • 트랜잭션 처리를 위한 SAGA 관리자 인스턴스(ORDER)가 별도로 존재
    • 트랜잭션에 관여하는 모든 어플리케이션은 관리자에 의해 순차적으로 트랜잭션을 수행하고 결과 전달
    • 마지막 트랜잭션이 끝나면 관리자를 종료하고 전체 트랜잭션 처리 종료
    • 중간에 Fail 발생시 매니저가 보상 트랜잭션을 발생시켜 일관성 유지
    • 즉, 관리자가 트랜잭션을 관리하여 분산 트랜잭션의 중앙 집중화를 이룸
    • 장점
      • 서비스간의 복잡성 감소 (구현 및 테스트 용이)
      • 트랜잭션 상태를 알고있는 매니저에 의해 롤백이 용이
    • 단점
      • 관리자를 위한 Orchestrator 서비스 추가로 인해 인프라 구현의 복잡도 증가

     

    — SAGA - 2) Choreography 방식

    • 보유한 서비스내(Application)에서 로컬 트랜잭션을 관리 → 트랜잭션 실패시 해당 Application에서 보상 이벤트를 발생시켜 롤백 처리
    • 순차적으로 트랜잭션 발생
    • 트랜잭션 종료 시 이벤트 발행 (다음 수행될 트랜잭션이 존재하면 다음 트랜잭션에게 이벤트 발행)
    • 이벤트는 kafka와 같은 메세지 큐를 이용해 비동기 방식으로 전달이 가능
    • 장점
      • 구성에 용이
    • 단점
      • 운영자가 트랜잭션의 현황을 파악하는데 어려움

     

     

     

    cf) 항상 SAGA 패턴이 옳은가?

    • 여러곳에서 트랜잭션을 처리하게 되면 복잡도가 증가하게 되므로 비지니스 로직상 트랜잭션 처리가 필요한 경우에만 사용하는 것이 좋음

     

     

     

     

     

    EDA (Event Driven Architecture) = Message Driven

    • 람다 베이스의 잘 디자인된 MSA 원칙
    • 특징
      • 이벤트를 이용하여 polling, webhooks를 대체
      • 복잡성 감소
      • scalability (확장성 증가)
      • 실시간 분석 가능
      • decoupling
      • dependency inversion
      • 단, 언제 어떻게 일어나는지에 대한 정보의 추적이 필요
    • 사용 시기 : performance 보다 scalability가 더 중요할 때

     

     

    • eventual consistency : 이벤트 송수신이 동시에 발생하지 않음 ⇒ 이벤트 분실 염려 감소
    • complexity : 이벤트가 서로 다른 다양한 이벤트를 유발시킬 수 있음
    • data replication / parallel processing : 이벤트에 따라서 각각의 서비스들이 각각의 데이터베이스에 정보 전달

     

     

     

     

     

     

    • kafka(pipe)를 이용하여 이루어진 이벤트 스트리밍 플랫폼
      • 하루에 조 단위의 이벤트 처리가 가능
      • 처음에는 분리된 commit log로 message queue로 인식되었으나 스트리밍 플랫폼으로 진화
    • 흐름 :
      1. 각각의 api가 Producer와 Consumer를 생성
      2. 사용자 정보 수정 이벤트 발생
      3. 서비스 플랫폼 api 선택
      4. 사용자 정보 수정
      5. kafka 이벤트 큐( topic )에 이벤트 추가
      6. 사용자 정보가 수정되는지 듣고있던 다른 api가 변화발생 감지
      7. Consumer api 데이터 베이스에 반영 (각각의 Consumer가 각각의 요청 처리)
    • 전체적인 흐름
      1. Producer가 정보(event)를 생성 후 topic (이벤트 큐)에 넣음
      2. Consumer가 소비하기 전까지는 이벤트가 큐에 존재 (kafka)
      3. Consumer가 소비하게 되면 큐에서 꺼내짐

     

     

     

     

    • Events
      • 소프트 웨어 시스템에서 발생할 수 있음
      • 이벤트를 통해 다른 액션을 유발 시킬 수 있음
      • 그룹화된 party들이 event 발생 시 전체 trigger가 될 수도 있음
      • 여기서 이벤트는 데이터를 포함하거나 그저 상황이 발생함을 알리는 용도로 사용될 수도 있음
      • IMMUTABLE
      • ex) 사용자 정보 업데이트, 카드 정보 수정 등
    • Event Streaming Architecture
      • 각각의 서비스가 이벤트 발생을 알림
      • 이벤트 큐의 party들이 관심있으면 queue에서 꺼내고 관심이 없으면 남겨둠
      • Tell / get 패턴 → 다른 party와 상관없이 사용자 정보가 바뀌면 tell하면 끝
    • Streaming Data
      • 일정한 정보의 흐름
      • 각각이 상태변화 이벤트에 대한 정보를 가져 실시간으로 시스템에 전달
      • 데이터 타입이나 이벤트의 성질이 결과적 액션에 영향

     

     

     

     

     

     

    예 ) 구매가 이루어졌을 때 구매에 대한 반응이 필요하지 않은 경우 / 예 ) 구매 이벤트에 대한 송수신이 decouple 되었지만 구매에 대한 반응이 요구되는 경우

     

     

     

     

     

     

    -EDA의 예시 1) External Integration

    • 외부와의 통합 예시
      • 1) AWS SES의 Email send 이벤트 발생
      • 2) Broker(메세지 큐)에 이벤트 등록
      • 3) 해당 이벤트를 듣고 있던 Consumer(Email, Webhooks)가 소비
      • 4) 각각 AWS SES, HTTP API 통신 (여기서 AWS SES 전달과 동시에 각각의 쓰레드나 프로세스를 통해 논리적 decoupling으로 HTTP API 전달 → HTTP API가 먼저 종료되고 그 후 AWS SES가 종료될 수도 있음)
      • 5) 이후 다른 이벤트인 SMS 이벤트 발생 (동일하게 진행)
      •  

     

     

     

     

     

     

    -EDA의 예시 2) Workflow

    • 실행 순서에 따라 차례대로 발생되는 workflow 형태
      • 1) 주문 이벤트 발생
      • 2) 주문 이벤트를 읽고 있던 Billing이 Order placed 이벤트를 소비
      • 3) 소비후 처리를 마친 Billing이 Order billed 이벤트 생성
      • 4) 이를 수신하고 있던 Warehouse가 이벤트 소비
      • 5) 이벤트를 소비한 Warehouse가 Shipping Label Created 이벤트 생성
      • 6) 이를 수신하는 Sales측에서 이벤트 소비
      •  

     

     

     

     

     

    -EDA의 예시 3) State Transfer

    • 상태변화 이벤트를 수신
      • 1) Producer가 상태변화에 대한 이벤트 생성 이벤트 큐에 등록
      • 2) 수신하는 Consumer가 이벤트를 수신
      • 3) 수신한 상태에 따라 Cache, DataWarehouse 등을 업데이트
      •  

     

     

     

     

     

     

    -EDA의 예시 4) Temporal decoupling

    • 만약 이벤트를 전달하는 과정에서 Consumer가 고장나는 상태가 발생한다면?
      • 일이 모두 중단되고 손실이 발생하는 것이 아닌, 고장난 Consumer가 다시 수행 가능 할 때까지 주문 생성이 이벤트 큐에서 계속 대기하고 있을 것

     

     

     

     

     

     

     

     

    Event sourcing

    • 이벤트를 통한 상태 전달이 가능 → event log를 통해서 이벤트 상태를 확인하는 것이 가능함
      • Complete Rebuild
      • Temporal Query
      • Event Replay ( 스냅샷 )
    • 전체 흐름
      • 이벤트 로그 : Day1. 상품이 추가됨 (10개)
      • 이벤트 로그 : Day2. 상품구매 발생 (1개)
      • 이벤트 로그 : Day3. 상품구매 발생 (1개)
      • 현재 상품 갯수 8개 저장 ⇒ 이벤트 로그를 통해서 8개임을 알 수 있음 (complete rebuild)
      • Day 정보를 통해서 시간 정보를 확인 가능 (temporary query)
      • 스냅샷 등 이벤트 로그를 통해서 이벤트를 다시 재생하는 것이 가능
      •  
    • 장점
      • 언제, 무슨 일이 발생하였는지 파악이 가능
      • reader, writer 가 많을 때 상태 파악에 유리
      • 이벤트 로그는 immutable (각각에 따라 알아서 프로세싱)
      • eventual consistency → 이벤트 로그를 통해서 비동기적으로 처리 및 확인 가능

     

     

     

     

     

     

     

    CQRS(Command - Query Responsibility Segregation)

    • CRUD(Create, Read, Update, Delete)에서 CUD(Command)와 R(Query)를 분리하는 것
    • 명령 조회 책임 분리
    • 왜 사용하는 가?
      • 데이터베이스로부터 데이터를 읽어오고 처리하게 되면 이미 그 사이에 데이터가 변경되었을 가능성이 높음
      • CQRS는 이러한 CUD와 Read사이의 delay가 존재함을 인정하는 것
      • + 도메인 또는 비지니스 규칙이 간단하고 간단한 CRUD 스타일의 사용자 인터페이스 및 데이터 액세스 작업으로 충분한 경우는 권장되지 않음
    • 장점
      • 각각에 더 최적화된 데이터 베이스 구성을 통해 성능 향상
      • Read에 의해 데이터가 변경되는 것을 방지
      • 과도하게 복잡한 모델을 덜 복잡하게 만듦 → 시스템 복잡도 감소
      • ex) Read의 경우 aggregation(집계함수) 등의 부가적인 attribute가 엔티티에 필요

     

     

    • 구현 방식
      • Event sourcing
      • Eventual Consistency
      • Domain Driven Design

     

     

     

     

     

     

     

     

    참고한 블로그  
     

    [Architecture] MSA : SAGA 패턴이란 - Azderica

    [Architecture] MSA : SAGA 패턴이란 Posted 22. December 2020. 7 min read. MSA : SAGA 패턴의 정의과 종류 이전에 MSA 개념에 대해 잡아보았습니다. 오늘은 MSA를 듣다보면 꼭 듣게 되는 SAGA 패턴에 대해 공부해보겠

    azderica.github.io

     

    CQRS 패턴, 코드에 순식간에 적용해보기

    서론 평화롭게 프로젝트를 개발하고 있던 어느 날, 우연한 기회로 CQRS 패턴에 대해 이야기를 들을 일이 생겼다. 기존 구조는 R.C.Martin의 Clean Architecture를 따라서 작업을 해둔 상태였는데, 어떤 프

    bluayer.com

     

    CQRS 패턴 알아보기

    들어가며  Event Driven Architecture에 대한 경험이 있으시거나, 혹은 그것에 관심이 있으신 분이라면 종종 CQRS라는 단어를 듣게 됩니다. 저 또한 종종 들었습니다. 하지만 정확하게 CQRS가 어떤 것인지

    always-kimkim.tistory.com

     

Designed by Tistory.