본문 바로가기
Semina

[우아콘2020] 배달의민족 MSA 여행기

by Jordy-torvalds 2022. 3. 28.
반응형

[우아콘2020] 배달의민족 MSA 여행기

 

우아콘2020 때 김영한 님이 발표한 배달의민족 마이크로서비스 여행기를 보고 정리해보았다. 방문자 분들은 나의 블로그 글보단 영상을 보고 직접 정리해보는게 더 좋을것 같긴 한다.

최초에는..

MSSQL DB와 PHP, 프로시저가 범벅이된 서비스. 온프리미스로 구성되어 있어서 일부 서비스에 장애가 나도 다른 곳에도 그것이 전파가 된다.

  • 자바 언어는 유스케이스가 많고 고스펙의 개발자를 수급하기가 쉬움.

2016년, 치킨 디도스

 

AWS이관이 불가한 결제를 제외하고는 치킨 이벤트에 필요한 프론트 서버와 주문 서버를 AWS로 옮기고 스케일링을 통해 많은 부하를 대응. 그림에 나오는 외부 PG는 타기업의 결제 서비스로 배달의 민족에서 부하를 모두 받아내고 이 요청을 다시 PG사에 재 전달을 하니 PG 사도 장애가 발생해서 장비를 2배 투입함으로써 대응함. 전 프로세스에 걸쳐 높은 트래픽에 대응할 수 있게 서비스가 개편됨.

2017년, 대 장애의 시대

매출과 트래픽이 늘은 만큼 장애 발생 빈도도 잦아짐. 그렇다보니 MSA와 클라우드 이관은 선택지가 아닌 생존의 문제였음

가게 목록과 검색을 분리함으로써 루비 데이터베이스에 가는 부하가 줄어듬.

2018년 상반기, 장애대응 TF

비즈니스와 시스템 안정성을 저울질 할 때 경영진 입장에서는 매출과 직결되는 비즈니스가 우선되기 마련. 하지만 적극적인 설득과 전사적인 공감을 얻은 끝에 장애대응 TF가 창설됨.

신속한 장애 대응을 위해서 PHP 였던 프론트 서버(가게상세)를 위와 같은 아키텍처로 바꿈으로써 안정적으로 서비스할 수 있도록 함. 조회 속도에 있어 RDB보단 NoSQL인 AWS DynamoDB가 비정규화된 데이터를 메모리에 기억하고 이를 제공하기 때문에 훨씬 빠르기 때문. 다만 실시간 싱크는 어렵고 변화에 있어 취약했음.

2018년 하반기

API로 동기식 통신하던 기존 방식. 하나의 API만 끊겨도 다음 단계가 진행되지 못한다..

그래서 개선한것이?!

EDA로 전환이다. 만약 리뷰 시스템이 죽어도 API로 인한 장애 전파가 되지 않게 되고,

복구 이후에 곧바로 컨슘 할 수 있게 된다.

→ 시스템 회복력이 증가!

추가적인 연동이 필요하면 꼽아서 쓰면 됨!

가게와 광고는 가장 역사가 오래된 도메인. 두 도메인은 1대1로 결합되어 있어 반정규화되어 있다보니 컬럼수가 무지막지하게 많음.

손보려고 해도 두 시스템의 결합도가 높다보니 한쪽만 손대서 떼어내는게 불가함.

이를 해결하기 위한 프로젝트 먼데이에 들어감.

루비에서 조회하는 서비스가 너무나 많음. 만약 루비에 문제가 생기면 관련된 모든 서버에 전파됨.

이를 해결하기 위해 CQRS 중 조회에 최적화된 서비스를 만들기 위해 시스템 전환 함.

하지만 단순히 API로 조회를 할 경우에 광고나 가게/업주에 문제가 생기면 관련된 마이크로서비스 들에 그 장애가 전파가 됨.

그리고 가게 노출에 들어오는 트래픽이 연계된 모든 서비스에 전파됨.

위 고려사항들에 대한 해결방안이 CQRS 였음. CQRS는 배달의민족 서비스 전반에 모두 적용됨

메뉴 변경이나 광고 변경이 발생하면 그 변경 사항에 대한 이벤트가 조회 쪽 서비스에 전달됨.

제로페이로드 방식의 선택 이유는 다음과 같음.

변경된 내용을 보낼 경우에는 변경된 내용에 대한 순서가 보장이 되어야하는데 그렇게 되면 고려해야할 내용이 굉장히 많아짐.

모든 내용을 보낼 경우에는 연관된 서비스가 원하는 데이터가 모두 다르므로 변경에 취약해짐 또한 관련된 테이블이 수십개이므로 현실성도 떨어짐.

각 시스템은 최소한의 필요한 데이터를 가진다. 각 시스템 내 데이터 간에는 물리적인 의존은 없으나 변경에 발생했을 때 싱크를 위한 노력이 많이 필요하므로 그 노력을 최소화 하기 위한 목적임.

각 시스템은 그 역할에 최적화된 데이터베이스를 사용하는 Polyglot 방식을 채택함.

시스템 별 사용하는 데이터 소스는 다음과 같음

이벤트를 통해 동기화 된 가게 데이터를 유지한다. 이 가게 데이터는 KEY-VALUE 형태로 되어 있으며 가게 ID로 조회를 하면 화면을 그리는데 필요한 모든 데이터가 FIT하게 정제되어 반환된다.

만약 검색을 한다고 하면 그 검색의 결과로 ID를 반환하며 반환 받은 ID로 자세한 정보는 가게 데이터로 부터 다시 조회를 한다.

또한 바로결제나 쿠폰의 상태는 비동기로 한다.

SNS, SQS가 안되도 IMPORT API를 통해서 변경 내용을 읽어오고 갱신함으로써 데이터 싱크 장애에 대응함.

최종적 일관성과 관련하여 주의해야할 사항은 다음과 같다.

만약 중식당 사장님이 짜장면을 짬뽕으로 메뉴명을 바꿧다고 해보자. 이때, 메뉴 변경이 완료되는데 까지는 이벤트 기반이다 보니 어쩔 수 없이 시간이 걸린다. 그런데 변경이 되기 전에 고객이 바뀌기 전 메뉴명인 짜장면으로 주문할 수 도 있다. 이러한 상황을 방어하기 위해 주문 전에 메뉴 시스템 쪽에 API를 통해 유효한지 확인을 한다. 하지만, 메뉴 시스템에 장애가 있거나 요청에 TIMEOUT이 발생해서 API가 정상적으로 처리되지 않을 수가 있다. 이러한 상황에 대해서는 개발 쪽과 기획이 협의가 필요하다. 결론적으론 위와 같은 상황은 정말 드물 것이므로 상황이 발생했을 때 회사에서 보상을 해주는 것으로 결정했다. 모든 것을 프로그래마틱하게 해결할 필요는 없는 샘이다.

마이크로서비스를 꼭 해야 하나요란 질문에 규모의 경제가 되어야 함을 강조했다.

  1. 시스템 규모
  2. 트래픽
  3. 전문 인력
  4.  

위 세 가지가 크게 필요하다. 간단하게는 조인으로 끝날 것이 복잡해지고 필요한 리소스가 많아지게 되는 것이다.

반응형