본문 바로가기
✈️ 시스템 설계

분산 메시지 큐 시스템 설계 1. 분산 메시지큐 주요 기능, 컴포넌트 설명과 초기 설계안

by kukim 2024. 2. 18.

이번 글에서는 분산 메시지 큐가 무엇인지 알아보고, 분산 메시지 시스템 설계를 한다는 가정하에 요구사항을 구체화하고 초기 설계안에 대해 설명하고자 합니다.

해당 내용은 가상 면접 사례로 배우는 대규모 시스템 설계 기초 2의 4장 분산 메시지 큐를 주로 참고하여 작성되었습니다.

 

목차

1. 서론

1.1 분산 메시지 큐의 중요성

1.2 분산 메시지 큐의 장점 / 단점

1.3 메시지 큐 vs 이벤트 스트리밍 플랫폼 

 

2. 설계에 앞서

2.1 요구사항 구체화 하기

2.2 기능 및 비기능 요구사항 정리

 

3. 주요 기능 / 컴포넌트

3.1 메시지 모델 (일대일 모델 / 발행-구독 모델)

3.2 토픽, 파티션, 브로커

3.3 소비자 그룹

3.4 초기 설계안

 

4. 마치며, 다음 글에서

Reference


1. 서론

1.1 분산 메시지 큐의 중요성

현대의 소프트웨어 아키텍처는 복잡한 시스템을 보다 관리 가능하고, 유지보수가 용이한 형태로 만들기 위해 잘 정의된 인터페이스를 경계로 나뉜 작고 독립적인 블록들로 구성되는 경향이 있습니다. 이러한 분산 시스템 설계에서, 분산 메시지 큐는 그 중추적인 역할을 담당하게 됩니다. 메시지 큐는 시스템 내의 다양한 컴포넌트, 블록들 간의 통신과 조율을 담당하며, 이를 통해 시스템의 전반적인 효율성과 안정성을 크게 향상시키는 역할을 합니다.

1.2 분산 메시지 큐의 장점

  • 결합도 완화(Decoupling): 메시지 큐는 시스템 내 컴포넌트 간의 강한 결합을 제거하여, 각 컴포넌트를 독립적으로 갱신하고 유지보수할 수 있게 합니다. 이는 시스템의 유연성을 크게 증가시키며, 변경 사항이 시스템 전체에 미치는 영향을 최소화합니다.
  • 규모 확장성 개선(Scalability): 메시지 큐는 생산자(Producer)와 소비자(Consumer)를 별도로 관리하여, 트래픽의 변화에 맞게 각각 독립적으로 스케일 업(scale-up)하거나 스케일 아웃(scale-out)할 수 있는 능력을 제공합니다. 이는 시스템의 확장성을 높이고, 다양한 부하 상황에 유연하게 대응할 수 있게 합니다.
  • 가용성 개선(Availability): 특정 컴포넌트에 장애가 발생해도, 다른 컴포넌트는 메시지 큐와의 상호작용을 통해 작업을 계속 수행할 수 있습니다. 이는 시스템의 전체 가용성을 높이며, 장애 발생 시 시스템의 안정성을 유지할 수 있게 합니다.
  • 성능 개선(Performance): 비동기 통신을 가능하게 함으로써, 생산자는 메시지를 큐에 전달하고 응답을 기다리지 않아도 됩니다. 마찬가지로, 소비자도 자신의 처리 속도에 맞춰 메시지를 처리할 수 있습니다. 이는 시스템의 전체적인 성능을 향상시키며, 컴포넌트 간의 의존성을 줄입니다.

1.2 분산 메시지 큐의 단점

  • 복잡성 증가: 분산 메시지 큐를 도입하면 시스템 아키텍처의 복잡성이 증가합니다. 메시지 큐 자체의 관리, 모니터링, 그리고 메시지 큐와 통신하는 다양한 서비스의 조정이 필요하게 됩니다. 이는 운영하는 입장에서 추가적인 학습과 노력을 요구할 수 있습니다.
  • 오버헤드: 메시지 큐를 통한 메시지 전달은 추가적인 네트워크 호출과 데이터 직렬화/역직렬화 과정을 포함합니다. 이는 시스템의 전반적인 성능에 미묘한 오버헤드를 추가할 수 있습니다.
  • 데이터 일관성 관리: 분산 메시지 큐 시스템은 데이터의 일관성 관리를 복잡하게 만들 수 있습니다. 특히, 분산 시스템에서는 메시지의 순서 보장, 중복 처리, 메시지 손실 등의 이슈를 관리해야 할 수 있으며, 이를 위한 추가적인 로직이 필요할 수 있습니다.
  • 장애 관리와 복구: 분산 시스템의 한 부분으로서, 메시지 큐도 장애에 취약할 수 있습니다. 큐 자체의 장애, 네트워크 문제, 또는 큐에 연결된 컴포넌트의 장애 등이 시스템 전체의 가용성에 영향을 미칠 수 있습니다. 따라서, 장애 발생 시 데이터의 안전한 복구, 메시지의 재처리 등을 위한 전략이 필요합니다.
  • 비용: 특히 클라우드 기반 메시지 큐 서비스를 사용하는 경우, 메시지의 양, 큐의 수, 데이터 전송량 등에 따라 비용이 증가할 수 있습니다. 비용 효율적인 시스템 설계를 위해 이러한 요소들을 면밀히 검토해야 합니다.

1.3 메시지 큐 vs 이벤트 스트리밍 플랫폼

엄밀하게 따지면 두 개를 구분할 수 있겠지만, 메시지 큐이벤트 스트리밍 플랫폼 간차이는 미비해지고 있습니다. 주로 데이터의 장기 보관, 메시지의 반복 소비 등 부가 기능을 갖춘 분산 메시지 큐들이 이벤트 스트리밍 플랫폼에서 지원됩니다. 이러한 기능들은 설계를 좀 더 까다롭게 만들 수 있으나, 현대의 대부분의 시스템은 이러한 기능들을 지원하는 추세입니다. 대표적인 기술로는 Apache Kafka, Pulsar, RabbitMQ, Redis pub/sub 등이 있으며, 이들 각각은 특정 사용 사례에 맞춰 최적화된 기능과 성능을 제공합니다.

 

RabbitMQ와 같은 전통적인 메시지 큐는 이벤트 스트리밍 플랫폼처럼 메시지 보관 문제를 중요하게 다루지 않는 편입니다. 또한 메시지 보관도 디스크에 영구적 저장보다는 일정 기간 동안 메모리에 보관시킵니다. 디스크에 보관되는 경우도 있지만 이벤트 스트리밍 플랫폼처럼 큰 용량은 아닙니다. 전통적인 메시지 큐는 메시지 전달 순서도 보존하지 않을 수 있는데요. 

 

전통적인 메시지 큐와 이벤트 스트리밍 플랫폼의 기능적 차이를 고려하여 설계를 해야 합니다.

이제 분산 메시지를 직접 설계하기 위해 문제를 이해하고 설계 범위를 정해볼까요?


2. 설계에 앞서 아키텍처 이해와 문제 범위 정하기

분산 메시지 큐를 직접 설계하기 위해 다양한 문제를 이해하고 설계 범위를 정해보고자 합니다. 이 과정에서 가상의 면접관에게 질문을 하고, 이를 통해 설계를 구체화 합니다.

2.1 요구사항 구체화 하기(면접관에게 Q&A)

1. 메시지 형태와 크기

  • 질문: 메시지의 형태와 크기는 어떻게 됩니까?
  • 답변: 메시지는 텍스트와 멀티미디어를 포함할 수 있으며, 크기는 주로 킬로바이트 수준입니다. 이를 통해 다양한 종류의 데이터를 효율적으로 처리할 수 있는 시스템을 설계해야 합니다.

2. 반복 소비 가능성

  • 질문: 메시지는 여러 소비자가 반복해서 수신할 수 있나요?
  • 답변: 예, 시스템은 메시지를 여러 소비자가 반복해서 수신할 수 있도록 설계되어야 합니다. 이는 메시지의 소비가 한 번에 끝나지 않고, 필요에 따라 여러 번 처리될 수 있음을 의미합니다.

3. 소비 순서

  • 질문: 메시지는 생산된 순서대로 소비되어야 하나요?
  • 답변: 예, 메시지는 생산된 순서대로 정확하게 소비될 수 있어야 합니다. 이는 특히 순서가 중요한 트랜잭션 처리에서 필수적인 요구 사항입니다.

4. 데이터 지속성

  • 질문: 데이터 지속성은 어떻게 보장되며, 기간은 얼마나 됩니까?
  • 답변: 데이터는 최소 2주간 저장되어야 하며, 디스크에 지속적으로 보관되어 여러 노드에 복제될 수 있어야 합니다. 이는 데이터의 안정성과 복구 가능성을 보장합니다.

5. 생산자 및 소비자 수

  • 질문: 생산자와 소비자의 수에는 제한이 있나요?
  • 답변: 시스템은 가능한 많은 수의 생산자와 소비자를 지원할 수 있어야 합니다. 이는 시스템의 확장성과 다양한 사용 사례를 수용할 수 있는 능력을 의미합니다.

6. 메시지 전달 방식

  • 질문: 지원하는 메시지 전달 방식은 무엇인가요?
  • 답변: 시스템은 최소 한 번, 최대 한 번, 정확히 한 번의 메시지 전달 방식을 모두 지원해야 합니다. 사용자는 자신의 요구에 맞게 전달 방식을 선택할 수 있어야 합니다.

7. 대역폭과 지연 시간

  • 질문: 목표 대역폭과 end-to-end 지연 시간은 어떻게 됩니까?
  • 답변: 시스템은 높은 수준의 대역폭을 제공하고 낮은 지연 시간을 보장해야 합니다. 이는 로그 수집 등 고성능이 요구되는 작업을 위해 필수적입니다.

2.2 기능 및 비기능 요구사항 요약

  • 기능 요구사항: 메시지는 반복 수신 가능해야 하며, 오래된 데이터는 자동으로 삭제되어야 합니다. 또한, 메시지 전달 방식은 사용자가 선택할 수 있어야 합니다.
  • 비기능 요구사항: 시스템은 높은 대역폭과 낮은 지연 시간 사이에서 선택할 수 있는 옵션을 제공해야 합니다. 또한, 규모의 확장성과 데이터의 지속성 및 내구성을 보장해야 합니다.

위 조건에 맞는 구체적인 설계에 앞서서 메시지 큐에서 사용되는 주요 기술, 컴포넌트들을 알아보고자 합니다.


3. 주요 기능 / 컴포넌트

먼저 메시지 큐의 기본 기능은 아래와 같습니다.

- 생산자는 메시지를 큐에 발행할 수 있다.

- 소비자는 큐를 구독(subscribe)하고 구독한 메시지를 소비할 수 있다.

- 메시지 큐는 생산자와 소비자 사이의 결합을 느슨하게 하는 서비스로, 생산자와 소비자의 독립적인 운영 및 규모 확장을 가능하게 하는 역할을 담당한다.

생산자와 소비자는 모두 클라이언트/서버 모델 관점에서 보면 클라이언트고 서버 역할을 하는 것은 메시지 큐이다.

메시지 큐 기본 기능

 

3.1 메시지 모델

3.1.1 일대일(point-to-point) 모델

전통적인 메시지 큐에 있는 모델로, 일대일 모델에서 메시지는 큐에 저장되며, 오직 하나의 소비자만 메시지를 가져갈 수 있습니다. 여러 소비자가 있을 경우에도 메시지는 단 한 번만 소비됩니다. 소비자가 메시지를 처리하고 큐에 수신 확인(acknowledge)을 보내면, 메시지는 큐에서 삭제됩니다. 이 모델은 데이터 보관(data retention)을 기본적으로 지원하지 않으며, 각 메시지는 한 번 소비되면 사라집니다.

(현재 설계하고자 하는 요구사항은 pub-sub 모델도 지원해야 합니다.)

일대일 모델

 

3.1.2 발행-구독(pub-sub) 모델

발행-구독 모델에서는 토픽(topic) 개념이 중심이 됩니다. 토픽은 메시지를 주제별로 분류하여 관리합니다. 생산자는 특정 토픽에 메시지를 발행하며, 이 메시지는 그 토픽을 구독하는 모든 소비자에게 전달됩니다. 이 모델을 통해 하나의 메시지가 여러 소비자에게 동시에 전달될 수 있습니다.

발행-구독 모델

3.2 토픽, 파티션, 브로커

3.2.1 토픽

메시지는 토픽에 의해 분류되어 보관됩니다. 하나의 토픽은 여러 메시지를 포함할 수 있으며, 이 메시지들은 관련된 주제 또는 카테고리를 기반으로 묶입니다. 만약 토픽에 보관되는 데이터 양이 커진다면 서버 한 대로 감당하기 힘든 상황이 발생할 수 있습니다.

 

3.2.2 파티션

토픽 내의 데이터가 많아져 한 서버로 처리하기 어려울 때, 파티션(partition) 또는 샤딩(sharding)을 통해 데이터를 분산 처리합니다. 파티션은 토픽의 메시지를 분할하여 저장하는 작은 단위이며, 메시지는 여러 파티션에 걸쳐 균등하게 분산됩니다. 각 파티션은 메시지 큐 클러스터 내의 서버에 고르게 배치되며, 이 서버들을 브로커라고 합니다.

파티션

 

3.2.3 브로커

브로커는 메시지 큐 시스템에서 파티션을 유지 관리하는 서버입니다. 각각의 브로커는 네트워크를 통해 서로 연결되어 있으며, 메시지의 저장 및 전달을 담당합니다.

각 파티션 내에서 메시지는 FIFO(First In First Out) 방식으로 관리됩니다, 즉, 같은 파티션 내에서는 메시지의 순서가 유지됩니다. 메시지의 위치는 '오프셋(offset)'으로 지정되며, 소비자는 이 오프셋을 사용하여 메시지를 읽습니다.

메시지 큐 클러스터

3.3 소바자 그룹

일대일 모델과 발행-구독 모델을 동시에 지원하는 시스템에서는 소비자 그룹의 개념이 필수적입니다. 소비자 그룹 내의 각 소비자는 토픽에서 메시지를 소비하기 위해 서로 협력하며, 하나의 소비자 그룹은 여러 토픽을 구독할 수 있습니다. 이 그룹 내의 소비자는 메시지를 병렬로 소비할 수 있으나, 같은 파티션의 메시지는 동시에 여러 소비자가 소비하지 않도록 관리됩니다.

- 소비자 그룹1은 토픽 A 구독하고 파티션마다 하나의 소비자 그룹만 소비(일대일 모델 지원)

- 소비자 그룹2은 토픽 A,B 구독 (토픽 A에 대해 구독-발생 모델 지원)

 

문제점과 해결책

  • 순서 문제: 한 파티션의 메시지를 여러 소비자가 병렬로 소비하려 할 때 순서를 보장하기 어려울 수 있습니다.
  • 해결책: 한 파티션에 대해서는 한 소비자 그룹 내의 오직 한 소비자만이 메시지를 읽을 수 있도록 설계합니다.
  • 제약사항: 소비자 그룹 내의 소비자 수가 토픽의 파티션 수보다 많을 경우, 일부 소비자는 작업을 수행하지 못하고 유휴 상태에 머무를 수 있습니다.
  • 해결책: 소비자 수와 파티션 수를 적절히 조절하거나, 모든 소비자를 같은 소비자 그룹에 포함시켜 일대일 모델을 구현합니다.

이러한 기술과 컴포넌트의 이해는 분산 메시지 큐 시스템을 설계할 때 필수적인 요소입니다. 이를 바탕으로 효율적이고 확장 가능한 시스템을 구축할 수 있습니다.

3.4 초기 설계안

초기 설계안

  •  클라이언트
    • 생산자: 메시지를 특정 토픽으로 보낸다
    • 소비자그룹: 토픽을 구독하고 메시지를 소비한다.
  • 핵심 서비스 및 저장소
    • 브로커: 파티션을 유지한다. 하나의 파티션은 특정 토픽에 대한 메시지의 부분 집합을 유지한다
    • 저장소
      • 데이터 자장소: 메시지는 파티션 내 데이터 저장소에 보관한다
      • 상태 저장소: 소비자 상태는 이 저장소에 유지
      • 메타데이터 저장소: 토픽 설정, 속성 등은 이 저장소에서 유지함
    • 조정 서비스(coordination service)
      • 서비스 탐색(service discovery): 어떤 브로커가 살아있는지 알려줌
      • 리더 선출(leader election): 브로커 가운데 하나는 컨트롤러 역할을 담당해야 하며, 한 클러스터에는 반드시 활성 상태 컨트롤러가 하나 있어야 한다. 이 컨트롤러가 파티션 배치를 책임진다.
      • 아파지 주키퍼나 etcd가 보통 컨트롤러 선출을 담당하는 컴포넌트로 이용

4. 마치며, 다음 글에서

지금까지 분산 메시지 큐 시스템의 중요성과 대규모 시스템 설계에서의 역할에 대해 알아보았습니다. 현대 소프트웨어 아키텍처의 필수 요소인 메시지 큐의 기본적인 장단점을 살펴보았고, 면접관과의 대화 형식을 통해 시스템 설계를 위한 기능 및 비기능 요구사항을 정리했습니다. 그리고 분산 메시지 큐에서 사용되는 주요 기술과 컴포넌트인 일대일 모델과 발행-구독 모델, 토픽과 파티션, 브로커, 그리고 소비자 그룹의 개념을 알아보았습니다.

 

3.4 초기 설계안에서 설명하지 못한 상태, 메타데이터 저장소나 조정 서비스를 설명하지 못했는데요.

다음 글에서 기초 지식을 바탕으로 실제 시스템의 상세 설계를 살펴볼 것입니다. 우리는 데이터의 장기 보관 방법, 적합한 데이터 저장소의 선택(관계형 데이터베이스와 쓰기 우선 로그의 비교), 메시지 자료 구조, 일괄 처리 방식, 생산자와 소비자 측의 작업 흐름, 푸시 대 풀 방식, 소비자 재조정, 상태 저장소와 메타데이터 저장소의 역할, 주키퍼의 사용, 데이터 복제 및 사본 동기화 방법, 시스템의 규모 확장성, 그리고 메시지 전달 방식의 다양한 선택지에 대해 깊이 있게 다룰 예정입니다.

 

감사합니다.


Reference

- Apache Kafka ARCHITECTURE - https://kafka.apache.org/21/documentation/streams/architecture.html

- 가상 면접 사례로 배우는 대규모 시스템 설계 기초 2 - 4장 https://m.yes24.com/Goods/Detail/124138645

- kafka 조금 아는 척하기 1 (개발자용) - https://youtu.be/0Ssx7jJJADI?si=DBIC_yWm121IEeqB

 

댓글