[NHN FORWARD 22] 분산 시스템에서 데이터를 전달하는 효율적인 방법
개인학습을 위하여 위 강연을 듣고 정리한 글입니다.
0. 분산 시스템
분산 시스템이란?
- 목표를 달성하기 위하여 여러 개의 컴퓨터 리소스를 사용하는 시스템
- 시스템은 두 개 이상의 컴포넌트로 구성되어 있다 (두 개 이상의 컴포넌트가 협업하여 하나의 기능을 수행)
- 앤터프라이즈 애플리케이션
- MSA 애플리케이션
- 모놀리식 아키텍처 애플리케이션 + 검색엔진
- 네트워크를 사용하여 컴포넌트 간의 기능을 통합
(네트워크를 사용하여) 데이터를 전달하는 방법
- Remote API (REST API, gRPC 등)
- 서버-클라이언트 구조 => 양쪽 다 데이터 처리 가능
- 서버에서 데이터를 처리 (C/U/D)
- 서버의 데이터를 가져와서 클라이언트에서 처리 (R)
- 사용자 요청에 즉각 응답하는 API에서 주로 사용하는 방식
- 비교적 간단한 개발 (컴포넌트 2)
- 서버-클라이언트 구조 => 양쪽 다 데이터 처리 가능
- MessageQueue
- Publisher - Consumer 구조 => 보통 Consumer가 데이터 처리
- Consumer가 데이터 처리 (C/R/U/D)
- 배치 작업, 비동기 작업에서 주로 사용
- 비교적 복잡한 개발 (컴포넌트 3)
- Publisher - Consumer 구조 => 보통 Consumer가 데이터 처리
분산 시스템에서 데이터를 전달하는 효율적인 방법
분산 시스템에서 모든 컴포넌트는 네트워크로 연결되어 있다
= 네트워크가 없으면 서로 통신할 수 x
- 네트워크는 시스템을 연결하는 유일한 수단
- BUT 네트워크는 신뢰할 수 없는 매체
- 패킷 손실
- 네트워크 지연
- 네트워크 다운
- 항상 데이터 유실에 대비
1. 데이터 전달 보장 방법론



1) At most once (최대 한번)
- Producer는 메시지를 최대 한번만 전송 (Fire and Forget)
- Consumer는 메시지를 최대 한번만 수신
- 네트워크상에서 데이터 유실될 수 있음
- Producer, Consumer 애플리케이션에서 예외 발생할수도
- 장점
- 간단한 구조
- 간단한 개발
- 단점
- 메시지 유실
2) At least once (최소 한번)
- Producer는 메시지를 최소 한번 이상 발송
- 발송 메시지 상태 관리
- Consumer는 메시지를 최소 한번 이상 수신
- ACK 유실로 인한 재발송
- 장점
- Producer는 메시지 발송 보장
- 효과 대비 쉬운 개발 (Producer에서만 상태관리하면됨)
- 단점
- Consumer가 같은 메시지를 여러번 받을 수도 + 순서 보장 x
=> 멱등성(idempotent)있게 개발해야함
- Consumer가 같은 메시지를 여러번 받을 수도 + 순서 보장 x
3) Exactly once delivery (정확히 한번)
- 메시지를 정확하게 한번만 전송
- 장점
- 누락과 중복 없다
- 단점
- 개발 난이도 가장 상
- Producer, Concemer에서 모두 상태 관리
- MessageQueue 기능에 의존한 개발
- MessageQueue 추가로 인한 시스템 복잡도 증가
2. RDB를 사용하는 애플리케이션에서 전달 방법


보편적으로 위처럼 서비스별로 DB를 가짐
트랜잭션 처리와 이벤트 전달이 실패없이 이뤄져야 한다면?

요 두가지를 섞어쓰면 된다


- Transactional Outbox Pattern
- RDB를 MQ처럼 사용
- 이벤트나 메시지를 RDB에 같이 저장 (하나의 트랜잭션에서)
- RDB를 MQ처럼 사용
- Polling Publisher Pattern
- demon이나 scheduler로 RDB에 저장된 이벤트를 주기적으로 Polling

- 장점
- REST API 환경에서 At least once를 구현할 수 있다
- 단점
- Polling, Publisher 과정으로 인한 지연 처리 -> 실시간성 필요한 데이터에는 사용x
- DB 부하
3. RabbigMQ를 사용한 전달 방법
RabbitMQ
- AMQP (Advanced Message Queuing Protocol) 을 구현한 메시지 브로커
- Publish/Subscribe 방식 지원
- ACK(Acknowledgement)라는 메시지 응답 처리 매커니즘 사용
- Producer Confirm : Publisher가 '나 메시지 잘 집어넣었어~'
- Consumer Ack : Consumer가 '나 메시지 잘 받았고, 잘 처리했어~'

Producer가 msg 발행
Exchange가 받아서 적절한 Queue에 넣음 (queue는 여러개 일 수 있으므로)
Consumer가 msg 빼감

근데 Routing(Exchange -> Queue)이 실패할 수도 있다 (cluster구조로 구성했을 경우 네트워크 타다가 라우팅 실패할 수도)
=> Producer Confirm으로 msg를 queue에 잘 넣었는지 알려줌


Dead Letter로 들어가는 경우
- Consumer Acknowlege NACK
- 오래된 msg
- queue가 가득참
4. Kafka를 사용하는 애플리케이션의 전달 방법
5. 마무리
- Event Driven Architecture의 기본은 데이터 전달
- 최소 At least once 설정
- Producer Confirm, Consumer Ack 고려
요새 너무 정신없이 회사일만 하는 것 같아서, 간간히 기술블로그를 읽거나 컨퍼런스 영상을 보려고 한다.
똑똑해지고 싶어라~
[NHN FORWARD 22] 분산 시스템에서 데이터를 전달하는 효율적인 방법
개인학습을 위하여 위 강연을 듣고 정리한 글입니다.
0. 분산 시스템
분산 시스템이란?
- 목표를 달성하기 위하여 여러 개의 컴퓨터 리소스를 사용하는 시스템
- 시스템은 두 개 이상의 컴포넌트로 구성되어 있다 (두 개 이상의 컴포넌트가 협업하여 하나의 기능을 수행)
- 앤터프라이즈 애플리케이션
- MSA 애플리케이션
- 모놀리식 아키텍처 애플리케이션 + 검색엔진
- 네트워크를 사용하여 컴포넌트 간의 기능을 통합
(네트워크를 사용하여) 데이터를 전달하는 방법
- Remote API (REST API, gRPC 등)
- 서버-클라이언트 구조 => 양쪽 다 데이터 처리 가능
- 서버에서 데이터를 처리 (C/U/D)
- 서버의 데이터를 가져와서 클라이언트에서 처리 (R)
- 사용자 요청에 즉각 응답하는 API에서 주로 사용하는 방식
- 비교적 간단한 개발 (컴포넌트 2)
- 서버-클라이언트 구조 => 양쪽 다 데이터 처리 가능
- MessageQueue
- Publisher - Consumer 구조 => 보통 Consumer가 데이터 처리
- Consumer가 데이터 처리 (C/R/U/D)
- 배치 작업, 비동기 작업에서 주로 사용
- 비교적 복잡한 개발 (컴포넌트 3)
- Publisher - Consumer 구조 => 보통 Consumer가 데이터 처리
분산 시스템에서 데이터를 전달하는 효율적인 방법
분산 시스템에서 모든 컴포넌트는 네트워크로 연결되어 있다
= 네트워크가 없으면 서로 통신할 수 x
- 네트워크는 시스템을 연결하는 유일한 수단
- BUT 네트워크는 신뢰할 수 없는 매체
- 패킷 손실
- 네트워크 지연
- 네트워크 다운
- 항상 데이터 유실에 대비
1. 데이터 전달 보장 방법론



1) At most once (최대 한번)
- Producer는 메시지를 최대 한번만 전송 (Fire and Forget)
- Consumer는 메시지를 최대 한번만 수신
- 네트워크상에서 데이터 유실될 수 있음
- Producer, Consumer 애플리케이션에서 예외 발생할수도
- 장점
- 간단한 구조
- 간단한 개발
- 단점
- 메시지 유실
2) At least once (최소 한번)
- Producer는 메시지를 최소 한번 이상 발송
- 발송 메시지 상태 관리
- Consumer는 메시지를 최소 한번 이상 수신
- ACK 유실로 인한 재발송
- 장점
- Producer는 메시지 발송 보장
- 효과 대비 쉬운 개발 (Producer에서만 상태관리하면됨)
- 단점
- Consumer가 같은 메시지를 여러번 받을 수도 + 순서 보장 x
=> 멱등성(idempotent)있게 개발해야함
- Consumer가 같은 메시지를 여러번 받을 수도 + 순서 보장 x
3) Exactly once delivery (정확히 한번)
- 메시지를 정확하게 한번만 전송
- 장점
- 누락과 중복 없다
- 단점
- 개발 난이도 가장 상
- Producer, Concemer에서 모두 상태 관리
- MessageQueue 기능에 의존한 개발
- MessageQueue 추가로 인한 시스템 복잡도 증가
2. RDB를 사용하는 애플리케이션에서 전달 방법


보편적으로 위처럼 서비스별로 DB를 가짐
트랜잭션 처리와 이벤트 전달이 실패없이 이뤄져야 한다면?

요 두가지를 섞어쓰면 된다


- Transactional Outbox Pattern
- RDB를 MQ처럼 사용
- 이벤트나 메시지를 RDB에 같이 저장 (하나의 트랜잭션에서)
- RDB를 MQ처럼 사용
- Polling Publisher Pattern
- demon이나 scheduler로 RDB에 저장된 이벤트를 주기적으로 Polling

- 장점
- REST API 환경에서 At least once를 구현할 수 있다
- 단점
- Polling, Publisher 과정으로 인한 지연 처리 -> 실시간성 필요한 데이터에는 사용x
- DB 부하
3. RabbigMQ를 사용한 전달 방법
RabbitMQ
- AMQP (Advanced Message Queuing Protocol) 을 구현한 메시지 브로커
- Publish/Subscribe 방식 지원
- ACK(Acknowledgement)라는 메시지 응답 처리 매커니즘 사용
- Producer Confirm : Publisher가 '나 메시지 잘 집어넣었어~'
- Consumer Ack : Consumer가 '나 메시지 잘 받았고, 잘 처리했어~'

Producer가 msg 발행
Exchange가 받아서 적절한 Queue에 넣음 (queue는 여러개 일 수 있으므로)
Consumer가 msg 빼감

근데 Routing(Exchange -> Queue)이 실패할 수도 있다 (cluster구조로 구성했을 경우 네트워크 타다가 라우팅 실패할 수도)
=> Producer Confirm으로 msg를 queue에 잘 넣었는지 알려줌


Dead Letter로 들어가는 경우
- Consumer Acknowlege NACK
- 오래된 msg
- queue가 가득참
4. Kafka를 사용하는 애플리케이션의 전달 방법
5. 마무리
- Event Driven Architecture의 기본은 데이터 전달
- 최소 At least once 설정
- Producer Confirm, Consumer Ack 고려
요새 너무 정신없이 회사일만 하는 것 같아서, 간간히 기술블로그를 읽거나 컨퍼런스 영상을 보려고 한다.
똑똑해지고 싶어라~