분산 시스템
목표를 달성하기 위하여 여러 개의 컴퓨터 리소스를 사용하는 시스템입니다.
시스템은 아래의 애플리케이션 모델 중 두 개 이상의 컴포넌트로 구성되어 있습니다.
- 엔터프라이즈 애플리케이션
- 마이크로 서비스 아키텍처 애플리케이션
- 모놀리식 아키텍처 애플리케이션 + 검색 엔진
이러한 시스템들이 네트워크를 사용하여 컴포넌트 간의 기능을 통합
데이터 전달
데이터를 전달하는 방법에는 두 가지가 있습니다.
- Remote API
- MessageQueue
Remote API
비교적 간단하게 개발할 수 있으며 사용자 요청에 즉각 응답하는 API에서 주로 사용하는 방식입니다.
서버 - 클라이언트로 이루어진 간단한 구조이며 아래의 특징이 있습니다.
- 서버에 데이터를 조작 (C/U/D)
- 서버의 데이터를 조회 (R)
MessageQueue
비교적 복잡하며 배치 작업, 비동기 작업에서 주로 사용됩니다.
Publisher - Consumer로 이루어진 구조이며 아래의 특징이 있습니다.
- Consumer가 데이터를 조작(C/R/U/D)
일반적으로 Publisher가 데이터를 만들어서 MessageQueue에 전달하면 Consumer는 Message를 받아서 데이터를 처리합니다.
효율적인 방법
분산 시스템에서 컴포넌트들을 네트워크로 연결
네트워크는 시스템을 연결하는 유일한 수단입니다. 하지만 패킷 손실, 네트워크 지연, 네트워크 다운등 여러 치명적인 이슈때문에 100% 신뢰할 수는 없습니다. 그렇기에 항상 데이터 유실에 대비를 해야합니다.
데이터 전달 보장 방법
RestAPI를 사용하거나 MessageQueue를 사용하거나 무엇을 사용하던 간에 Endpoint에서 부터 Endpoint까지 데이터를 전달하는 추상화된 방법론을 의미합니다.
At Most Once (최대 한번)
Producer는 메시지를 최대 한번만 전송(Fire and forget)하고 Consumer는 메시지를 최대 한번만 수신합니다. 하지만 네트워크가 유실될 수 있으며 Producer/Consumer 애플리케이션에서 예외가 발생할 수 있습니다.
- 장점 : 간단한 구조 / 간단한 개발
- 단점 : 메시지 유실
At Least Once (최소 한번)
Producer는 메시지를 최소 한번 이상 발송하는데 이때 발송 메시지의 상태를 관리합니다. Consumer는 메시지를 최소 한번 이상 수신하는데 ACK 유실로 인한 재발송 문제가 발생할 수 있습니다.
장점 : Producer는 Messgae 발송 보장, 효과 대비 쉬운 개발
단점 : 멱등성(Idenpotent)을 보장해야 하는 Consumer. (같은 메시지를 여러번 받더라도 최종 메시지는 같아야 한다.)
Exactly Once (정확히 한번)
메시지는 정확하게 한번만 전송합니다.
장점: 누락과 중복이 없음
단점 : 가장 어려운 개발 난이도, Producer / Consumer에서 모든 상태 관리, MessgaeQueue 기능에 의존한 개발, MessageQueue 추가로 인한 시스템 복잡도 증가
여러분의 애플리케이션은 데이터를 어떻게 전달하나요? 최소 한번은 전달하나요?
신뢰성 있는 애플리케이션이 되기 위해서는 적어도 최소 한번은 전달 해야 하는데, 만약 Spring Boot를 사용하는데 기본 설정이나 getting start의 설정을 복붙해서 사용한다면 최소 한번 전달하기 어렵습니다.
RDB를 사용하는 애플리케이션에서 전달 방법
서비스별 데이터베이스 패턴 (Database per Service Pattern)
즉, 서비스마다 독립된 DB가 존재하며 각각 처리를 합니다.
마이크로서비스 아키텍처 패턴
Transactional Outbox Pattern
- RDB를 MessageQueue로 사용
- OLTP에 Event Message를 포함하는 패턴
Polling Publisher Pattern
- RDB Message Queue Polling & Publishing
이 4개의 필드는 꼭 명시가 되어 있어야 합니다.
장점
- REST API 환경에서 At-least-once를 구현할 수 있다.
단점
- Polling, Publisher 과정으로 인한 지연 처리가 발생한다.
- 데이터 베이스가 과부하 될 수 있다.
- 데이터 베이스 크기에 비례한 처리 속도
RabbitMQ를 사용한 전달 방법
AMQP(Advanced Message Queuing Protocol)을 구현한 메시지 브로커입니다.
Publish/Subscribe 방식을 지원하며 ACK를 메시지 응답 처리 메커니즘으로 제공합니다.
Produce가 메시지를 잘 발행하면 Exchange가 해당 메시지를 받습니다. 그 후 적절한 Queue에 메시지를 전달하며 Queue에 들어간 메시지는 Consumer는 Listen해서 메시지를 읽게 됩니다.
하지만 Routing이 실패한다면?(네트워크 문제로 인해)
exchange가 성공하면 ACK, 실패하면 NACK의 응답 값을 produer에게 전달합니다. -> Producer Confirm
Consumer도 마찬가지로 메시지를 잘 받았으면 ACK를 반환함으로써 Queue에 있는 메시지를 삭제합니다. -> Consumer Achnowledge
Consumer가 메시지를 잘 받지 못해 NACK를 반환한다면 Queue에는 메시지가 계속 쌓이게 됩니다. 이런 경우에 Dead Letter를 설정하면 됩니다.
Queue에서 정상적으로 처리되지 못한 메시지들은 Dead Letter Exchange에게 넘기고 Dead Letter Queue에게 넘깁니다.
Dead Letter Exchange로 넘기는 조건은 3가지가 존재합니다.
1. 오래된 메시지
2. NACK를 반환한 메시지
3. Queue가 가득 차서 더이상 처리할 수 없을 때
마무리
분산 시스템에서 데이터를 전달하는 효율적인 방법은 아래와 같이 정리할 수 있습니다.
- Event Driven Architecture 의 기본은 데이터 전달
- 최소 At Least Once(최소 한번) 설정
- Producer Confirm, Consumer Ack 고려
'칼럼 이야기 > 영상' 카테고리의 다른 글
트래픽과 네트워크 성능 지표 (0) | 2024.08.02 |
---|---|
Kubernetes에서 DNS 다루는 방법 - 도메인을 찾아서 (0) | 2024.07.26 |
[DevArt] Devops란 무엇일까? (0) | 2024.04.06 |