일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Kubernetes
- 정보처리기사 실기
- mysql 튜닝
- CKA
- Java
- MySQL
- IntelliJ
- aws
- CKA 기출문제
- 티스토리챌린지
- kotlin
- 공부
- APM
- 정보처리기사 실기 기출문제
- kotlin querydsl
- kotlin spring
- 정보처리기사실기 기출문제
- kotlin coroutine
- Pinpoint
- 코틀린 코루틴의 정석
- Elasticsearch
- minikube
- CloudWatch
- Spring
- 오블완
- PETERICA
- Linux
- AI
- 기록으로 실력을 쌓자
- AWS EKS
- Today
- Total
피터의 개발이야기
[MSA] 마이크로서비스란? - 배민 마이크로서비스 여행기를 보고... 본문
ㅁ 관련 글
ㅇ [MSA] 마이크로서비스 - 분산 트랜잭션 처리를 위한 Saga 패턴
ㅁ 들어가며
마이크로서비스의 패턴 중 CQRS에 관한 글을 작성하면서 [우아콘2020] 배달의민족 마이크로서비스 여행기 유튜브 동영상을 다시 보게 되었다. MSA에 대해 고민하면서 많이 공감이 되고 도움이 되는 동영상이다. 이번에 이 동영상을 다시 보면서 마이크로서비스를 구축하는 좋은 경험들을 글로 정리를 해 보았다.
주의: 동영상을 보면서 마이크로서비스를 공부하는 상황이라 동영상의 내용과 나의 생각이 혼합되어 있다.
ㅁ 마이크로서비스 이해를 위한 핵심 질문들
동영상을 통해 마이크로서비스를 이해하는 핵심적 내용은 다음 질문으로 귀속된다.
왜 나누어야 하고, 나누었을 때 상호 통신과 데이터 일관성은 어떻게?
ㅇ 분해
- 왜 기존 서비스를 마이크로서비스로 전환해야 할까요?
ㄴ 늘어나는 트래픽을 어떻게 소화해야할까?
ㄴ 어떻게 커져만 가는 모노리틱 서비스에서 MSA 전환으로 설득하지?
- 기존에 하나였던 모노리틱 아키텍처에서 서비스를 어떻게 분해할까?
ㄴ 핵심키워드: 도메인 주도 패턴(DDD)
ㅇ 통신
- 분해된 서비스들 간 통신은 어떻게 진행해야할까?
ㄴ Sync(Http): 모듈간 API - 데이터 분리는 되었지만 API가 죽으면...
ㄴ Async(AWS SNS): 배민은 AWS SNS를 사용했지만, rabbitmq나 kafka
ㅇ 트랜잭션
- 분산된 데이터의 트랜잭션은 어떻게 할까?
ㄴ 2PC(Two-Phase Commit)와 보상 트랜잭션(Compensae Transaction)
ㄴ SAGA 패턴: 코레오그래피(서비스 중심), 오케스트레이션(중앙 집중)
ㄴ 이벤트 소싱 + EDA
ㄴ MSA와 데이터 일관성의 딜레마에서 결단은 최종적 일관성(Eventually Consistency)
ㅇ 데이터 쿼리
- 모듈별 분산된 데이터는 어떻게 쿼리할까?
ㄴ AWS DynamoDB 등 Multi Datasource를 활용한 CQRS
ㄴ Write와 Read 분리
:- 비지니스 로직이 포함된 복잡한 데이터 쿼리와 단순 View를 위한 조회 쿼리의 분리
:- 서비스 포퍼먼스를 위해 비정규화를 통해 일부 중복된 데이터를 허용
=> 데이터 동기화 문제, 분산 트렌젝션 문제 발생
ㄴ 조회 쿼리: CQRS View Dynamo DB 서비스로 구현
아래는 동영상을 보면서 캡처하고 내용과 생각을 정리한 부분이다.
ㅁ 왜 나누어야 하는가? - 급성장하는 서비스
ㅇ 기존 서비스는 모노리틱 아키텍처로 디비를 중심으로 여러 Application이 "통짜"로 구축되어 있었다.
ㅇ 주문이 년간 8만건 정도이면 문제가 되지 않지만 사용자가 늘어나면 지연 및 부하로 인한 장애가 발생하게 된다.
ㅇ 개인적인 생각으로 서비스 확장 정도에 따라서 단계가 있다고 생각한다.
1단계: DB 스팩을 최대한 올린다.
ㄴ 모노리틱의 가장 확실한 대처는 스케일업이다.
모노리틱 구조에서는 디비를 스케일아웃하기는 어렵다.
2단계: 대용량, 고트래픽으로 인해 DB 병목 발생
ㄴ 1단계의 한계점에 도달했다.
DB의 성능을 최대치로 올려도,
내부적인 테이블의 구조나 기타 네트워크 IO 혹은 디비락 등의 문제로 장애가 자주 발생하게 된다.
마이크로서비스의 필요성이 대두된다.
3단계로 부하 분산을 위한 마이크로서비스 구축:
ㄴ 부하 분산을 위해 Cloud인 AWS를 사용하기 시작
ㄴ 마이크로서비스를 구축을 위한 설계 검토
4단계 장애의 연속
ㄴ 처음부터 MSA를 잘하는 사람은 없다.
ㄴ 사업과 마케팅은 안정성과 이윤창출을 원하지만, 개발자는 핵폭탄이 보인다.
ㅁ 장애의 연속
ㄴ 프론트가 죽어서 서버 늘렸더니, 주문이 죽고, 나중에 PG사가 죽더라...
ㄴ 김영한님 왈: 진짜 생존을 위해서 우리는 마이크로서비스를 해야하는 구나...
ㅁ 트래픽 분산을 위한 NoSQL 사용 및 희미한 CQRS 패턴 적용
ㅇ Write와 Read 역할을 구분하여 디비 부하를 줄이자
ㄴ루비DB는 Write, update 및 관계형 디비 비지니스 로직 수행(무거운 조인쿼리 구동)
ㄴAWS 다이나모DB를 통해 단순 select를 빠르게 대응
ㄴ 일종의 NoSQL은 Read Insert는 빠르지만, 관계형 SQL은 구조상 조화하기 어려움.
ㅁ 달리는 마차의 바뀌를 바꾸어라!!
ㅇ 회사의 이윤창출은 곧 트래픽과 연관된다. 지속적인 성장은 이윤을 남기지만, 반대로 시스템의 불안정을 만들게 된다.
ㅇ 통으로 된 레거시 시스템을 모듈화하고 새로운 시스템으로 도약하는 과정을 설명함.
ㅁ 서비스간 통신은? - Event Driven Architecture
ㅇ Sync 기본 API 기반 데이터 전달
ㄴ50X 에러가 나면... 다른 연동 API가 장애가 나면 요청들은 유실된다.
ㅇ 이벤트 기반으로 데이터를 전달하면,
- 연동 시스템 간의 느슨한 결합
ㄴ 이벤트를 발생할테니 다른 부서는 참조해서 처리해...
- 요청 데이터 유실 방지
ㄴ 장애가 나도 다시 하면 된다.
- 성능 업이나 시스템 업그레이드 용이함.
ㄴ 배포 전략에 따라 순단이 발생하겠지만, 유실된 정보는 없다.
ㅇ 동영상: EDA설명 링크
ㅁ MSA 구조로의 전환
ㅇ 결합도를 낮추기 위해 서로 API로 조회...
ㄴ 어느 하나가 장애가 발생하면, 응답을 기다린다고 홀딩... => 전체 장애
ㅇ MSA 구조로 변경하지만 성능, 장애 격리, 데이터 동기화를 고려해야 한다.
ㅁ 성능, 장애 격리
ㅇ 점심, 저녁, 이벤트 시 버스트 트래픽 발생
ㅁ 데이터 동기화 해결책 = CQRS + EDA
ㅇ CQRS 패턴을 적용하여, DB 부하는 분산
- 명령(Command): 핵심 비즈니스 영역, Creat, Update, Delete
- 조회(Query): 사용자 서비스 중심, Select Join
- 장점: 명령 혹은 조회에 특화된 DB 혹은 NoSQL을 선택할 수 있다.
ㅇ 이벤트 전파와 동기화
- Eventually Consistency(최종적 일관성)
ㄴ 나는 결과론적 일관성이고 표현함.
ㄴ 데이터베이스의 일관성과 MSA의 격리성에 따른 딜레마가 발생.
- 데이터는 언젠가는 다 맞추어진다.
- 데이터 싱크 1~3초
- 문제 발생 시 해당 시스템의 이벤트 재발행
- 대부분 Zero-Payload
ㄴ 누가, 어떤 이벤트 인지만 전달.
ㄴ 업데이트 시 상세조회로 세부정보 요청.
- 장점: 명령 혹은 조회에 특화된 DB 혹은 NoSQL을 선택할 수 있다.
ㅇ 광고리스팅, 검색, 찜 시스템의 모듈들에서 가게ID만 받아 자체 DB에서 정보를 조회
ㅇ 비동기 작업을 통해 동시에 일을 처리하여 속도 개선
ㅁ CQRS 성능 및 장애 격리
ㅇ 트래픽이 발생하여도 내부 DB에서 조회하여 뒷단의 메인 디비에는 영향이 전파되지 않음.
ㅇ 장애격리
ㄴ 각 시스템이 내부에 필요한 데이터 보관
ㄴ 내부 서비스의 변경 내역은 이벤트로 동기화
ㄴ 장애 시 데이터 싱크가 늦어져도 고객서비스는 가능
ㅁ 데이터 싱크 장애 대응
ㅇ 원천 모듈에서 이벤트 재발행
ㅇ 큐 장애 발생 시
ㄴ 전체 IMPORT API를 통해 배치로 동기화
ㄴ 부분 IMPORT API를 통해 동기화
- 최근 명분간의 데이터를 조회 및 동기화 처리
ㅇ 서킷 브레이커 패턴(Circuit Breaker Pattern) 적용
ㄴ 장애가 발생했다면 지속적인 요청을 장애를 악화 시킴.
ㄴ 장애 시 요청을 보내지 않도록 차단시켜 실패할 수 있는 작업을 계속 시도하지 않도록 방지한다.
ㅁ 정리
ㅇ 배달의 민족에서 수행한 거대한 CQRS 패턴을 공부하게 됨.
ㅇ 성능이 중요한 외부 시스템과 비즈니스 명령이 많은 내부 시스템으로 분리
ㅇ 이벤트 발행을 통해 Eventually Consistency(최종적 일관성)을 유지
ㅇ 각 시스템은 API 또는 이벤트 방식으로 연동
ㅇ 마이크로서비스는
데이터의 비정규화 방식을 고수하고 번거로운 수작업이 많지만,
그래도 성능과 장애격리 및 데이터 동기화를 위해 어쩔 수 없이 꼭! 필요하다.
ㅁ 마이크로서비스 꼭 해야되나?
ㅇ 규모의 경제가 되어야 한다. 시스템 규모, 트래픽, 사람...
ㄴ 테이블 조인으로 해결될 일을 10배 힘들게 MSA로 구성해야 한다.
ㅁ 내가 경험한 마이크로 서비스란?
마이크로서비스는 정말 어쩔 수 없어서 쓰는 것이지, 편안해서 쓰는게 절대 아니다.
고객에겐 우리의 장애를 알리지 말라!!
마이크로서비스는 결과적으로 안정된 서비스를 위해 더 많은 고군분투가 필요하다.
ㅁ 함께 보면 좋은 사이트
'Kubernetes > 기초공부' 카테고리의 다른 글
[MSA] 12가지 마이크로서비스 패턴 (0) | 2024.03.02 |
---|---|
[MSA] 마이크로서비스란? (0) | 2024.02.29 |
[MSA] 마이크로서비스 - 분산 트랜잭션 처리를 위한 Saga 패턴 (0) | 2024.02.27 |
[kubernetes] command, env 문법 공부 (0) | 2024.01.24 |
[kubernetes] Deployment이란? 서비스 중단, 무중단 배포방법 (0) | 2024.01.21 |