MSA를 구현할때 각 서비스별로 분리된 데이터베이스를 관리합니다. 이 상황에서 화면으로 전달될 데이터가 하나의 서비스에 국한될 가능성은 거의 없을 것입니다. 이때 BFF 와 같이 각 서비스와 통신하여 데이터를 모아주는 역할을 하는 서비스가 존재하게 됩니다.
이때 데이터를 동기화하는 다양한 패턴이 있지만, 실시간으로 데이터를 동기화해야하는 경우에는 gRPC 가 적합하다 판단했습니다. 이 글에서는 왜 그렇게 생각했는지 정리했습니다.
MSA 에서 데이터 동기화 패턴
Chris Richardson의 Microservice Pattern에 따르면 <데이터 동기화 패턴> 이라는 용어가 적합하지 않을 수 있습니다. 이 글에서 말하는 데이터 동기화 패턴이란 마이크로 서비스 환경에서 사용자의 요구에 따라 일관성있는 데이터를 전달하기 위한 패턴으로 정의하겠습니다. 그리고 데이터 동기화 패턴에는 다음의 것들이 있습니다:
1. API 기반 동기화
서비스들이 필요한 데이터를 실시간으로 다른 서비스의 API를 통해 요청하여 가져옵니다.
장점
- 데이터가 필요한 순간에 요청을 통해 실기간으로 데이터를 동기화할 수 있다는 점,
- 해당 데이터를 획득하기 위한 프로토콜만 맞추면 된다는 점에서 다소 결합도가 낮은 방법이라는 장점이 있습니다.
단점
- 다만 네트워크 지연 및 호출 빈도에 따라 성능이 영향을 받을 우려가 있어 Loadbalancing 이 주요하며
- 요청을 받아서 처리하는 서비스의 상태에 따라 데이터 품질이 달라진다는 점에서 Service Discovery 를 고려해야할 뿐만 아니라 SPOF 문제도 내포하고 있습니다.
예시
- REST API, Remote Procedure Call 등 각 서비스간 포로토콜에 기반한 통신을 포함합니다.
2. 이벤트 기반 동기화 (메시지 큐 활용)
데이터 변경 시, 변경 이벤트를 메시지 큐를 통해 발행하고, 구독 서비스들이 이를 받아 로컬 데이터를 업데이트합니다. (사가패턴 등)
장점
- 서비스간 느슨한 결합을 유지할 수 있으며 DLQ를 활용하여 장애허용(fault tolerance)도가 높은 시스템을 기대할 수 있습니다. 또한 polling 방식을 이용하여 더 안전하게 이벤트 동기화를 처리할 수 있습니다.
단점
- 실시간 데이터 동기화 구현을 위해 pushing 방식을 채택한다면 멱등성(idempotency) 보장을 위해 별도의 설계가 추가되어야하며,
- 트랜잭션 동기화를 위해 Saga Pattern 을 도입한다면 전체 MSA 설계가 어려워지는 측면이 존재합니다.
예시
- 메시지 큐(예: Kafka, RabbitMQ)를 이용한 트랜잭션 동기화가 있습니다.
3. Change Data Capture (CDC) / ETL 기반 동기화
CDC는 데이터베이스에서 발생하는 변경 사항(Insert, Update, Delete)을 실시간 또는 준실시간으로 캡처하여 다른 서비스나 데이터 저장소로 전파하는 기술입니다. 주로 데이터 동기화, 실시간 분석, 이벤트 기반 아키텍처 구축 등에서 사용됩니다. ETL(Extract, Transform, Load)은 추출된 데이터를 변환하고 목적지 시스템에 적재하는 일련의 작업을 의미합니다.
아직 직접 해본적이 없어서 다소 이론적인 내용들입니다.
장점
- 데이터가 변경되는 즉시 이를 캡처하여 동기화하기 때문에 실시간 데이터 일관성 보장에 매우 효과적이라고 알려져있습니다.
- 분산 데이터베이스 환경에서도 안정적이면서 효율적인 동기화를 지원하는것으로 알려져있습니다.
단점
- CDC 프로세스를 관리하기 위한 추가 인프라를 운영해야 하며, 장애 관리 및 모니터링 시스템 구성이 복잡해질 수 있습니다.
- CDC 프로세스가 중단될 경우 데이터 유실 또는 데이터 복제 지연 등의 문제가 발생할 수 있어서 역시 설계가 복잡해집니다.
예시
- Debezium과 Kafka를 활용한 실시간 데이터 복제, AWS Database Migration Service(DMS) 등이 있습니다.
결국 어떤 동기화 전략을 선택해야하나
결국 실시간으로 데이터를 동기화하는 선택지로는 API 기반 동기화와 CDC 기반 동기화가 있습니다. 그런데 CDC로 접근하는것은 공부가 부족하기도 하지만 관련 유지보수 비용이 높아진다는 부담이 존재했습니다. 그래서 API 기반 동기화를 선택하게 되었습니다.
그렇다면 API 기반 동기화 중 구체적으로 어떤 프로토콜을 이용할것인지 정해야합니다.
1. RPC(gRPC)와 GraphQL 중 어떤 프로토콜을 선택할지에 대한 고민
RPC란?
- Remote Procedure Call의 약자로, 원격에서 함수를 호출하는 방식입니다. 대표적으로 gRPC가 있으며, Protocol Buffers를 이용해 데이터 구조를 정의합니다.
- 주로 서비스 간 빠른 속도와 효율적이고 엄격한 규격이 필요할 때 사용합니다.
GraphQL이란?
- Facebook에서 개발된 데이터 쿼리 및 조작을 위한 쿼리 언어입니다.
- 클라이언트가 데이터를 정확히 원하는 대로 요청하여 받을 수 있고, Subscription을 통해 데이터 변경을 실시간으로 구독할 수 있습니다.
gRPC vs GraphQL 간 주요 비교
gRPC | GraphQL | |
데이터 형식 | Protocol Buffers | JSON |
통신 프로토콜 | HTTP/2 (binary) | HTTP (주로 POST 방식) |
성능 | 우수(낮은 지연, 높은 성능) | 양호(하지만 데이터 선택성으로 효율성 높음) |
실시간성 | Streaming 방식 지원 | Subscription 지원 |
데이터 유연성 | 낮음(정의된 데이터 형식만 가능) | 매우 높음(필요한 데이터만 선택 가능) |
클라이언트 접근성 | 낮음(엄격한 정의 필요) | 높음(쿼리 유연성, 클라이언트 친화적) |
유지보수 | schema 관리 부담 존재 | schema 진화 용이 |
2. 기술의 선택
이번 데이터 동기화의 고민은 주로 내부 서비스간 데이터를 동기화하는것이 이슈였습니다. 내부 통신이기에 서비스간 엄밀한 타입 정의가 중요하며, 성능이 가장 우선시 되어야 했습니다.
그런 측면에서 데이터 타입 유연성이 뛰어난 GraphQL을 선택하기보다 RPC가 적합했으며, 특히 gRPC는 HTTP2 를 이용하여 다수의 요청을 비동기적으로 처리할 수 있다는 것도 큰 장점이었습니다. 이러한 이유로 RPC, 그 중에서도 가장 대표적인 gRPC를 선택하게 되었습니다.
참고
- BFF Pattern, Sam Newman: https://samnewman.io/patterns/architectural/bff/
- Microservice Patterns, Chris Richardson: https://microservices.io/patterns/index.html
'탐구 생활 > python gRPC' 카테고리의 다른 글
python gRPC (2) - 기본 구조와 python 구현 (0) | 2025.03.08 |
---|