대규모 시스템이란?(2)

2024. 9. 26. 09:58대규모스트림처리

2024/09/26

 

 

이전 포스팅에서 대규모 시스템이 무엇인지 알아보았습니다.
오늘은 대규모 시스템에 대해 추가적으로 살펴보겠습니다.

 

 

※  대규모 시스템에 대해 더 살펴보자.

 

   ▶ 대규모 시스템

       ●  데이터 일관성 유지

 📌 대규모 시스템에서는 데이터 일관성을 유지하는 것이 중요하다. 이를 위해 분산 트랜잭션, 이벤트 소싱, CQRS(Command Query Responsibility Segregation) 등의 기법을 사용할 수 있다.

 

        1️⃣ 분산 트랜잭션

            ○  분산 트랜잭션은 여러 개의 독립된 시스템이나 데이터베이스에서 동시에 일어나는 트랜잭션을 일관되게 관리하는 방법이다.
            ○  단일 트랜잭션이 여러 시스템에 걸쳐 발생할 때, 모든 시스템이 해당 트랜잭션을 성공적으로 완료하거나, 모든 시스템이 트랜잭션을 실패로 처리하도록 보장한다. 이를 통해 데이터의 일관성을 유지할 수 있다.
            ○  분산 트랜잭션이 필요한 이유는 마이크로서비스 아키텍처에서 여러 서비스가 독립적으로 운영되기 때문이다.


          💡 주요개념

             ✅ 트랜잭션(Transaction) 

데이터베이스의 상태를 변환하는 작업의 단위로,
ACID(원자성, 일관성, 고립성, 지속성) 속성을 보장한다.


               ▪  원자성(Atomicity): 트랜잭션은 전부 성공하거나 전부 실패하여, 부분적인 작업 수행이 없는 것을 보장한다.
               ▪  일관성(Consistency): 트랜잭션이 완료된 후에도 데이터베이스는 모든 무결성 제약 조건을 유지한다.
               ▪  격리성(Isolation): 동시에 실행되는 트랜잭션이 서로 간섭하지 않도록 보장한다.
               ▪  지속성(Durability): 트랜잭션이 성공적으로 완료된 후의 결과는 시스템 장애가 발생해도 영구적으로 유지된다.

 

             ✅ 분산 트랜잭션(Distributed Transaction):

여러 분산된 데이터 소스에 걸쳐 트랜잭션을 수행하는 작업이다.
예를 들어, 여러 마이크로서비스나 데이터베이스에서 데이터를 동시에 업데이트하는 경우가 이에 해당한다.


             ✅ 2PC (Two-Phase Commit):

분산 트랜잭션을 관리하는 프로토콜로,
준비(Prepare) 단계와 커밋(Commit) 단계로 나누어 트랜잭션을 처리한다.


               ▪  준비 단계(Prepare Phase): 각 참여 노드는 트랜잭션 준비 상태를 확인하고, 준비 완료를 마스터 노드에 알린다.
               ▪  커밋 단계(Commit Phase): 마스터 노드는 모든 참여 노드가 준비되었음을 확인하고, 트랜잭션을 커밋하도록 지시한다. 만약 준비가 완료되지 않은 노드가 있다면 트랜잭션을 롤백한다.

 

             ✅ 사가 패턴(Saga Pattern):

트랜잭션을 여러 단계로 나누어 처리하고, 각 단계가 독립적으로 커밋된다.
실패 시 보상 트랜잭션을 실행하여 상태를 롤백한다.


               ▪  주문 생성 단계: 사용자가 주문을 생성한다.
               ▪  결제 처리 단계: 결제 서비스가 주문 결제를 처리한다.
               ▪  재고 감소 단계: 재고 서비스가 주문된 상품의 재고를 감소시킨다.
               ▪ 
각 단계가 성공적으로 완료되면 다음 단계로 넘어가고, 실패하면 이전 단계에서 수행된 작업을 취소한다.

 

             ✅ 이벤트 소싱(Event Sourcing):

상태 변화를 이벤트로 기록하고, 해당 이벤트를 재생하여 현재 상태를 유지한다.
이를 통해 분산 트랜잭션의 일관성을 유지할 수 있다.

 

          💡 분산 트랜잭션의 장점

             ①  데이터 일관성 보장 :
               ▪  분산된 여러 데이터 소스에 걸쳐 일관된 데이터 상태를 유지할 수 있다.
               ▪  모든 트랜잭션이 성공적으로 완료되거나 모두 실패하도록 보장한다.

              ②  확장성 :
               ▪  분산 트랜잭션을 통해 여러 시스템이 독립적으로 동작하면서도, 필요한 경우 협력하여 일관된 상태를 유지할 수 있다.
               ▪  이를 통해 시스템의 확장성을 높일 수 있다.

              ③  신뢰성 :
               ▪  트랜잭션의 ACID 속성을 분산 환경에서도 유지할 수 있어 시스템의 신뢰성을 높인다.
               ▪  데이터 무결성과 일관성을 유지할 수 있다.

              ④  복구 가능성 :
               ▪  트랜잭션 실패 시 롤백 메커니즘을 통해 상태를 복구할 수 있어, 시스템 안정성을 높일 수 있다.

 

          💡 분산 트랜잭션의 단점

             ①  복잡성 증가:
               ▪  분산 트랜잭션을 구현하고 관리하는 것은 복잡하다.
               ▪  특히, 여러 시스템 간의 트랜잭션 동기화와 데이터 일관성을 유지하는 것은 어려운 작업이다.

              ②  성능 저하:
               ▪  2PC와 같은 프로토콜을 사용할 경우, 트랜잭션의 준비와 커밋 단계에서 지연이 발생할 수 있다.
               ▪  이는 시스템의 성능을 저하시킬 수 있다.

              ③  네트워크 오버헤드:
               ▪  여러 시스템 간의 통신이 필요하므로 네트워크 오버헤드가 증가할 수 있다.
               ▪  이는 트랜잭션 처리 속도를 저하시킬 수 있다.

              ④  복구의 어려움:
               ▪  분산 트랜잭션 실패 시, 모든 시스템에서 일관된 상태로 롤백하는 것이 어려울 수 있다.
               ▪  특히, 부분적으로 실패한 트랜잭션을 처리하는 데 어려움이 있을 수 있다.

 

           ➡️  분산 트랜잭션의 예시

             📍주문 생성과 결제 처리:

                ▪  한 사용자가 온라인 쇼핑몰에서 주문을 생성하고, 결제를 진행한다.
                ▪  이 과정에서 주문 서비스와 결제 서비스가 각각 독립된 데이터베이스를 사용한다고 가정한다.
                ▪  분산 트랜잭션을 통해 두 서비스가 일관되게 주문과 결제를 처리해야 한다.
                ▪  트랜잭션이 성공적으로 완료되면 두 데이터베이스에 주문 및 결제 정보가 일관되게 저장된다.

             📍2PC를 사용한 트랜잭션 처리:

                ▪  준비 단계: 주문 서비스와 결제 서비스가 트랜잭션을 준비한다. 두 서비스가 모두 준비 완료 상태를 마스터 노드에 알린다.
                ▪  커밋 단계: 마스터 노드는 두 서비스가 모두 준비되었음을 확인하고, 트랜잭션을 커밋하도록 지시한다. 만약 하나의 서비스라도 준비되지 않았으면, 트랜잭션을 롤백한다.

 

 

        2️⃣ 이벤트 소싱

            ○  이벤트 소싱은 데이터 상태 변화를 이벤트로 기록하고, 해당 이벤트들을 순차적으로 재생하여 현재 상태를 파악하는 방법이다.
            ○  전통적인 데이터 저장 방식과 달리, 이벤트 소싱에서는 데이터 변경 자체가 아닌 변경 이벤트를 저장한다.
            ○  이러한 방식은 특히 복잡한 비즈니스 로직을 다루는 시스템에서 데이터 일관성과 추적 가능성을 높이는 데 유용한다.
            ○  하지만 복잡성이 증가할 수 있으므로, 시스템의 요구사항에 따라 신중하게 적용해야 한다.

 

          💡 주요 개념

             ✅ 이벤트(Event):

데이터의 상태 변화를 나타내는 기록이다.
예를 들어, "주문 생성", "결제 완료", "주문 취소" 등이 이벤트가 될 수 있다.


             ✅ 이벤트 스토어(Event Store):

이벤트를 저장하는 저장소다.
전통적인 데이터베이스 대신 이벤트를 순서대로 저장하는 스토리지다.
이는 이벤트의 불변성과 순차성을 보장한다.


             ✅ 애그리게이트(Aggregate):

관련된 이벤트를 모아 현재 상태를 재현할 수 있는 엔터티다.
애그리게이트는 도메인 모델의 일부분으로, 이벤트를 적용하여 상태를 변화시킨다.


             ✅ 커맨드(Command):

애그리게이트에 특정 동작을 지시하는 명령이다.
커맨드는 이벤트를 생성하는 트리거 역할을 한다.


             ✅ 프로젝션(Projection):

이벤트를 읽기 모델로 변환하여 조회 성능을 최적화하는 방식이다.
이벤트를 기반으로 읽기 전용 데이터베이스를 업데이트한다.



          💡 이벤트 소싱의 장점

             ①  데이터 변경 이력 추적:
               ▪  모든 상태 변화를 이벤트로 기록하므로, 데이터 변경 이력을 완벽하게 추적할 수 있다.
               ▪  이는 감사와 디버깅에 유용하다.

              ②  복구 및 재생:
               ▪  이벤트를 재생하여 시스템의 현재 상태를 복구할 수 있다.
               ▪  이는 데이터 손실이나 시스템 장애 시 유용하다.

              ③  CQRS와의 자연스러운 통합:
               ▪  이벤트 소싱은 CQRS(Command Query Responsibility Segregation)와 잘 어울린다.
               ▪  명령과 조회를 분리하여 성능과 확장성을 최적화할 수 있다.

          💡 이벤트 소싱의 단점

             ①  복잡성 증가:
               ▪  시스템 설계와 구현의 복잡성이 증가한다.
               ▪  이벤트 모델링과 이벤트 스토어 관리가 필요하다.

              ②  읽기 성능:
               ▪  이벤트를 재생하여 현재 상태를 계산해야 하므로, 읽기 성능이 저하될 수 있다.
               ▪  이를 해결하기 위해 프로젝션과 CQRS를 활용할 수 있다.

 

 

         3️⃣ CQRS

            ○  CQRS는 명령(Query)과 조회(Query)의 책임을 분리하는 소프트웨어 디자인 패턴이다.
            ○  이 패턴은 읽기 작업과 쓰기 작업을 서로 다른 모델로 분리하여, 각 작업에 최적화된 구조를 사용할 수 있도록 한다.
            ○  CQRS는 시스템의 성능, 확장성, 유지보수성을 향상시키는 데 도움이 된다.

 

          💡 주요 개념

             ✅ 명령(Command):

데이터를 변경하는 작업이다.
예를 들어, 주문 생성, 결제 처리, 계정 업데이트 등이 명령에 해당한다.
명령은 데이터베이스에 대한 쓰기 작업을 수행한다.

               ▪  명령 모델은 데이터의 상태 변경을 담당한다.
               ▪  이는 복잡한 비즈니스 로직을 포함할 수 있으며, 데이터 무결성을 보장하기 위해 트랜잭션을 사용한다.

 

             ✅ 조회(Query):

데이터를 조회하는 작업이다.
예를 들어, 주문 내역 조회, 계정 정보 조회 등이 조회에 해당한다.
조회는 데이터베이스에 대한 읽기 작업을 수행한다.

               ▪  조회 모델은 읽기 전용 데이터베이스 또는 캐시를 사용하여 빠른 응답을 제공한다.
               ▪  이는 단순한 데이터 조회를 위한 최적화된 구조를 가질 수 있다.

 

          💡 CQRS의 장점

             ①  성능 향상:
               ▪  읽기와 쓰기를 분리하여 각 작업에 최적화된 데이터 저장소와 인프라를 사용할 수 있다.
               ▪  예를 들어, 조회 성능을 높이기 위해 읽기 전용 데이터베이스를 사용하거나, 캐시를 활용할 수 있다.

              ②  확장성:
               ▪  읽기와 쓰기를 독립적으로 확장할 수 있다.
               ▪  예를 들어, 읽기 요청이 많은 경우 조회 모델을 수평으로 확장하여 부하를 분산시킬 수 있다.

              ③  유지보수성:
               ▪  비즈니스 로직이 명령 모델에 집중되므로, 복잡한 상태 변경 로직을 관리하기 쉽다.
               ▪  또한, 읽기 모델은 단순화되어 유지보수하기 용이하다.

              ④  데이터 일관성:
               ▪  CQRS는 이벤트 소싱과 잘 어울린다.
               ▪  이벤트 소싱을 통해 데이터 상태 변경을 이벤트로 기록하고, 이벤트를 재생하여 현재 상태를 유지할 수 있다.
               ▪  이를 통해 데이터 일관성을 보장할 수 있다.

 

          💡 CQRS의 단점

             ①  복잡성 증가:
               ▪  시스템 설계와 구현의 복잡성이 증가한다.
               ▪  명령 모델과 조회 모델을 각각 설계하고 관리해야 한다.

              ②  데이터 동기화:
               ▪  명령 모델과 조회 모델 간의 데이터 동기화가 필요하다.
               ▪  이는 추가적인 구현과 관리가 필요하다.

 

 

 

 

'대규모스트림처리' 카테고리의 다른 글

Kafka란?  (3) 2024.10.01
RabbitMQ란?  (0) 2024.09.30
대규모 시스템이란?(3)  (2) 2024.09.29
대규모 시스템이란?(1)  (4) 2024.09.25