책너두 (도메인 주도 설계로 시작하는 마이크로서비스 개발) 10일차 (~85p)

요약

  • 애플리케이션 패턴의 나머지 부분에 대해 이해함.
    • 쓰기 최적화: 이벤트 소싱 패턴
      • 이벤트 소싱 패턴은 객체 상태 변경 이벤트를 계산하지 않고 이벤트 저장소에 저장함으로써 메시지 발행 및 저장 처리의 원자성을 보장하고 성능을 최적화하는 방법임.
      • 이벤트 저장소는 이벤트 데이터베이스 역할과 메시지 브로커처럼 작동하여 쓰기 성능을 최적화하고, 정확한 감사 로깅을 제공하며, 객체의 예전 상태를 재구성하는 것이 간단해짐.
  • 3장. 마이크로서비스의 애플리케이션 아키텍처에 대해 이해함.
    • 비즈니스 로직에 대한 관심사 분리
      • 비즈니스 로직은 시스템의 핵심이며, 관심사의 분리 원칙을 따름.
      • 비즈니스 로직 영역과 기술 영역은 철저히 분리함으로써 유지보수성이 높아짐.
      • 데이터베이스 중심 아키텍처의 문제점으로 인해 관심사의 분리 원칙을 지키는 것이 필요함.

메모

쓰기 최적화: 이벤트 소싱 패턴

  • 지금까지 살펴본 사가 패턴 & CQRS 패턴에서는 비즈니스 불일치를 피하기 위해 저장소에 저장하는 것과 메시지를 보내는 것이 원자성을 지녀야 했음.
    • 즉, 저장소에 저장하는 일과 메시지를 보내는 작업이 언제나 완전하게 진행되어 함께 실행돼야 했음.
    • 하지만, 객체 상태 변화를 이벤트 메시지로 발행하고, 객체 상태를 관계형 데이터베이스에 저장하는 경우, SQL 질의어로 변환해서 처리하기가 매우 번거롭고 까다로움.
    • 그리고,메시지 발행과 저장 처리라는 두 가지 기능을 수행하므로 빠르지도 않음.
  • 메시지 발행 및 저장 처리의 원자성을 보장하고, 성능도 최적화하는 방법은 무엇인가?
    • 보통 비즈니스 처리를 수행할 때, 데이터 처리는 항상 처리 상태의 결과값을 계산하고, 데이터의 최종 상태를 확정해서 저장하는 방식으로 진행됨.
    • 따라서, 이 같은 과정은 복잡해지고 변환 처리로 느릴 수밖에 없음.
    • 특히, 인스턴스가 여러 개로 확장될 때 동시 업데이트 및 교착상태로부터 안전하지 못할 수도 있음.
      • 객체 상태를 데이터 모델에 맞춰 계싼하지 않고, 상태 트랜잭션 자체를 저장한다면?
        • 이를 이벤트 소싱(event sourcing) 기법이라고 함.
          • 트랜잭션 자체를 저장하자는 전략임.
          • 상태 변경 이벤트를 계산해서 데이터 모델로 변경하지 않고, 바로 이벤트 저장소에 그대로 저장함.
        • 이를 이용하면 메시지 브로커와 데이터 저장소를 분리하지 않고 하나로 사용할 수 있음.
          • 복잡한 과정도 없어서 쓰기 속도도 훨씬 빨라짐.
        • 만약, 현 시점의 상태가 필요하다면?
          • 상태의 출발점부터 모든 기록된 상태 변경 트랜잭션을 순차적으로 계산한다.
          • 처음부터 모든 트랜잭션 처리가 부담되면 매일 자정에 상태를 계산한 후, 스냅숏으로 저장한 후, 현재 상태 정보가 필요해지면 스냅숏 이후의 트랜잭션만 처리하면됨.
          • 이 방식은 특정 시점의 상태가 필요하면 재현할 수 있기 때문에 별도의 트랜잭션성 이력 로그 데이터를 기록할 필요도 없음.
        • 명령 측면과 조회 측면의 서비스가 이벤트 저장소에 대한 CRUD를 모두 처리할 필요 없이, CR만 처리하면 됨.
          • 저장소에서 변경과 삭제가 발생하지 않기 때문에 명령 측면의 서비스를 여러 개 확장해도 동시 업데이트 및 교착상태가 발생하지 않음.
  • 정리하면, 이벤트 소싱은 모든 트랜잭션의 상태를 바로바로 계산하지 않고, 별도의 이벤트 스트림으로 이벤트 스트림 저장소에 저장하는 방식임.
    • 이벤트 스트림 저장소는 오로지 추가만 가능하게끔 해서 계속 이벤트들이 쌓이게 만듦.
    • 실제로 내가 필요한 데이터를 구체화하는 시점에서는 그때까지 축적된 트랜잭션을 바탕으로 상태를 계산해서 구성함.
    • 이벤트 저장소는 이벤트 데이터베이스 역할 뿐만 아니라 메시지 브로커처럼 작동함.
      • 데이터 저장 처리 메커니즘과 메시지 큐 같은 이벤트를 전달하기 위한 메커니즘을 통합해서 복잡성을 줄이고 특히, 쓰기 성능을 최적화함.
    • 상태를 저장하기 때문에 정확한 감사 로깅을 제공함.
    • 객체의 예전 상태를 재구성하는 것이 간단해짐.
    • 외부 애플리케이션에 이벤트를 전달하는 것도 저장한 이벤트를 그대로 전송하면 되기 때문에 간편함.

03. 마이크로서비스 애플리케이션 아키텍처

  • 로버트 C. 마틴은 소프트웨어의 가치를 행위 가치(기능)구조 가치(아키텍처)로 나누며, 구조 가치가 소프트웨어를 부드럽게 만든다고 주장함.
    • 코드와 설계의 구조를 무시하고 기능 구현만 추구할 경우, 소프트웨어 유지보수가 어렵고 비용이 많이 들어간다고 강조함.
  • 실무에서는 애플리케이션 구조설계에 신경 쓰지 않고 기능 구현에만 집중한 소프트웨어의 유지보수가 어려려움.
    • 마이크로서비스팀은 초기 개발뿐 아니라 지속적인 비즈니스 변화에 대응할 수 있는 구조가 필요함.
  • 이 장에서는 MSA 내부 아키텍처를 살펴봄,
    • 기존 애플리케이션 아키텍처의 연장선에서 고려해야 할 사항을 살펴봄.
    • 마이크로서비스와 접목되는 바람직한 애플리케이션 아키텍처 아이디어와 내부 설계 시 고려해야 할 애플리케이션 패턴을 살펴봄.

3.1 비즈니스 로직은 어디에? - 관심사의 분리

  • 소프트웨어 개발에서 비즈니스 로직은 시스템의 핵심이며, 이를 잘 표현하는 것이 중요함.
    • 관심사의 분리(separation of concerns) 원칙은 시스템을 이해하고 변경하기 쉽게 만들어 줌.
    • 이 원칙에 따라 각 영역은 고유 관심사에 의해 분리되고 집중돼야 함.
  • 특히, 비즈니스 로직 영역과 기술 영역은 철저히 분리하는 것이 좋음.
    • 이렇게 함으로써 복잡성이 낮아지고 유지보수성이 높아짐.
    • 하지만 현장에서는 관심사의 분리 원칙이 지켜지지 않고 비즈니스 로직이 대부분 SQL에 몰려 있는 경우가 많음.
    • 이러한 상황은 특정 개인이나 기술에 의존하게 되어 유지보수가 어려워지고 시스템 변경이 힘들어짐.
  • MSA 시스템을 유연하고 확장성 있게 만들기 위해서는 마이크로서비스의 내부 구조를 어떻게 유연하게 만들 것인지가 중요함.
    • 따라서 기술과 비즈니스 로직을 분리하여 기술의 변화에도 비즈니스 로직이 영향받지 않고 쉽게 변경 및 확장이 가능한 바람직한 마이크로서비스 내부 구조를 고려해야 함.

3.1.1 데이터베이스 중심 아키텍처의 문제점

  • 데이터베이스 중심 아키텍처는 관계형 데이터베이스에 의존한 데이터 모델링을 수행하고, 이를 중심으로 애플리케이션을 구현하는 방식임.
    • 이러한 구조에서 비즈니스 로직은 대부분 서비스에 존재해야 하지만, 실제로는 테이블과 SQL 질의에 존재하게 됨.
    • 이로 인해 아래와 같은 문제점이 발생함.
      1. 유연성과 확장성 부족
        • 저장 기술과 비즈니스 로직이 밀접하게 결합되어 있어, 저장소 변경 시 다시 구현해야 하는 경우가 많음.
      2. 성능 의존성
        • 대부분의 성능이 데이터베이스에 의존하며, 애플리케이션은 별도로 할 일이 없기 때문에, 데이터가 늘어남에 따라 성능 저하가 발생함.
      3. 클라우드 인프라 활용 어려움
        • 데이터베이스 중심 아키텍처는 클라우드 인프라의 가장 큰 장점인 자동 스케일 아웃을 제대로 활용하기 어려움.
  • 따라서, 클라우드의 풍부한 자원환경에서는 애플리케이션의 확장성과 유연함이 더 중요하므로, 관심사의 분리 원칙에 따라 비즈니스 로직 처리와 데이터 처리를 철저히 분리하는 것이 필요함.

댓글

Designed by JB FACTORY