레이블이 Microservice인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Microservice인 게시물을 표시합니다. 모든 게시물 표시

6/22/2022

Monolith 잘라 내기

현실에서 마이크로 서비스 관련 설계를 진행하다 보면, 적합하지 않은 상황이 발생하곤 한다. 이런 상황에 대해서 언급하는 글(https://dzone.com/articles/chopping-the-monolith-the-demo)을 발견해서 내용을 작성한다. 저자는 전자 상거래 영역에서 몇 년간 일을 했다고 한다. 전자 상거래의 상당 부분이 가격 책정에 전념하고 있고 가격 책정 규칙은 매우 자주 변경된다고 한다.

  • 특정 제품의 재고가 너무 많음
  • 시즌 종료: 새 상품에 대한 물류 센터 공간을 확보해야 하기에, 가격을 낮춰서 판매한다.
  • 연구에 따르면 마진을 낮추면 제품 판매가 증가하여 전반적으로 더 많은 수익이 발생한다고 한다.
  • 마케팅 목적

저자는 관련해서 예제로 코드를 만들었다. 아래는 전자 상거래 예시 화면이다.


장바구니에 항목을 추가하고 내용을 확인할 수 있는 기능이다.


초기 상황

아래 시퀀스 다이어그램은 기존 방식을 설명한다.

CheckoutHandler에서 장바구니 담기와 가격 책정 기능을 모두 포함하고 있다.

가격 책정

가격 책정 기능을 분리해야 한다. 그 이유는 이 글 처음에 작성했다. 새로운 시퀀스 다이어그램은 아래와 같다.


새로운 시퀀스 다이어그램에서는 몇 가지 변경 사항이 포함된다.

  • 가격은 분리되어 제공된다.
  • CheckoutView는 더 이상 가격 정보를 반환하지 않는다.
  • 클라이언트는 결제와 가격 책정 사이의 흐름을 조정한다.

가격 책정 서비스 대체


가격 책정 기능을 분리하여 사용하기로 결정했다면, API Gateway Pattern을 적용하여 외부에 노출되는 API와 Backend 서비스의 접점을 분리시켜줘야 한다. Apache APISIX Gateway는 실시간으로 경로 구성이 가능하고 클라이언트에 노출된 URL을 변경하지 않고도 신규 추가된 가격 책정 서비스의 API와 매핑이 가능하다.

결론

저자는 본 글에서 마이크로 서비스를 사용하지 말아야 하는 이유에 중점을 두고 예제 코드를 작성했다고 언급하고 있다. 마이크로 서비스 대신 특정 부분을 전용 서비스로서의 기능으로 분리할 수 있다고 한다.

내가 생각하기에는 이런 작업들이 계속 반복된다면, 결국 아래의 방식으로 서비스가 쪼개질 것이라고 생각한다. 처음 시작은 Monolith에서 필요에 의해 기능을 분리하는 방식으로 진행했지만, 결국에는 Monolith가 마이크로 서비스로 점진적으로 마이그레이션 되는 방식이라 생각한다.

물론, 저자가 의도한 바는 New features 단계(아래의 첫번째 단계)라고 볼 수 있다.


이 글을 읽는 분들은 이 상황에 대해서 어떻게 생각하시는지요?

References:


9/14/2020

Microservice와 Monolith 선택 가이드

우선 이 글을 읽기전에 이전에 작성했던 글을 먼저 읽어 보길 바랍니다.

  • 마이크로 서비스에 대해서 생각해보기

프로젝트를 시작할 때 기술 스택에 대해서 고민을 합니다. 아키텍처 관점에서는 크게 두 가지가 있습니다. 일반적으로 “마이크로서비스” 또는 “모놀리식” 둘 중 하나를 선택을 합니다.

위 두가지 중에 어떤 아키텍처를 선택해야 할까요? 본 글에서는 모놀리식 아키텍처와 마이크로서비스 아키텍처를 선택하는 방법에 대해서 언급하려고 합니다.

모놀리식 아키텍처와 마이크로 서비스 아키텍처 선택하기

두 가지 접근 방식은 고유한 장/단점을 지니고 있습니다. 백엔드 아키텍처를 선택할 때 선택의 자유가 있다는 얘기입니다. 그러나 우리는 선택을 해야 하고, 방향을 결정 할 때, 도움이 되는 몇 가지 질문을 생각해보세요.

익숙한 분야의 비즈니스인지?

고객의 니즈와 업무 도메인을 알고 있는 상황에서 일할때에는 명확한 설계가 용이합니다. 하지만 새로운 비즈니스에서는 달라집니다. 비즈니스가 익숙치 않기 때문에 고려해야 할 요소의 양이 많기 때문입니다.

따라서 마이크로 서비스 아키텍처를 사용하는 것은 비즈니스를 완전히 이해하는 경우에 적합합니다. 그렇지 않으면 모놀리식 방식으로 진행하는 것이 좋습니다.

Team은 준비되어 있는지?

팀원들이 마이크로 서비스를 구현하는 방법을 모두 숙지하고 있는지 확인을 해야 합니다. 아니면 모놀리식의 단순성내에서 작업하는 것을 더 선호하는지에 대해서도 확인해야 합니다. 과거 프로젝트를 수행시 고객사의 팀원들은 마이크로 서비스보다 모놀리식 방식으로 개발 하는 것을 더 선호했습니다. Lerning Curve 기간이 끝난후에는 괜찮아졌지만, 이에 대해 시간을 할애하거나 팀원들이 새로운 기술을 받을 수 있는 준비가 되었는지를 고려해야 합니다. 이 질문에 대해 답을 할 수 있으면 마이크로 서비스를 선택하세요.

인프라 환경은 준비되어 있는지?

마이크로 서비스는 개발에서 배포에 이르기까지 클라우드 기반 인프라를 사용하는 것이 유리합니다. 당신이 속한 곳에서 클라우드 환경을 이용할 수 있는지 확인해보세요.

비즈니스의 위험을 평가했나요?

대부분의 기업은 마이크로 서비스가 자신들의 비즈니스에 적합하다고 생각합니다. 하지만, 그들이 만든 애플리케이션이 비즈니스적으로 기대한 만큼 성장하거나 확장되지 않을 가능성이 존재합니다. 비즈니스가 계속 성장하고 확장될 수 있다라는 확신이 들면 마이크로 서비스를 선택하시길 바랍니다.

모놀리식은 언제 선택하나요?

  • 팀이 최초 만들어졌을때
  • 비즈니스 PoC를 진행 할 때
  • 마이크로 서비스에 대한 경험이 없는 경우

마이크로 서비스는 언제 선택하나요?

  • 독립적으로 빠른 배포가 필요할 때
  • 비즈니스를 확장하거나 팀을 확장해야 할 때
  • 매우 효율적인 플랫폼을 구축해야 할 때
  • Waterfall과 같은 방식이 아니라 Agile방식으로 서비스를 진화시켜야 할 때
  • 프로젝트 기간이 촉박하지 않을 때

결론

마이크로 서비스와 모놀리식을 현 시장에서 비교하자면 전자가 Hot하다는 것은 부정할 수 없습니다. 대부분의 의사결정권자들은 자신의 애플리케이션이 마이크로 서비스 아키텍처를 기반으로 한다고 말하고 싶어합니다. 그러나 마이크로 서비스에만 집중하고 비즈니스 도메인과 역량을 고려하지 않는다는 것은 위험하고 위의 질문들을 기반으로 마이크로 서비스가 줄 수 있는 실제 가치를 측정해야 합니다.

가장 현명한 접근 방식은 모놀리식으로 접근하여 새로운 애플리케이션을 개발하고 운영을 하면서 “성능 모니터링”, “비즈니스 확장성”등과 같은 백데이터를 근거로 마이크로 서비스의 정당성을 확보한 경우에 이동하는 것입니다. (물론, 모놀리식으로 개발을 하더라도 Package단위로는 서비스가 분리되는 것이 좋겠지요. 미래를 위해…)

기존 비즈니스의 경우, 비즈니스가 익숙한 상황이고 티밍이 되어있고 비즈니스가 확장되고 있다면, 마이크로 서비스를 고려할 수 있습니다. 그러나 스타트업이나 새로 시작하는 회사에서는 마이크로서비스를 채택하면 성공에 부정적인 영향을 미칠 가능성이 높습니다.

위에 언급한 내용을 보시고 잘 판단하셔서 아키텍처를 선정 하시길 바랍니다.

11/18/2019

마이크로 서비스(MSA) 관련 Tool

마이크로 서비스 Tool이라고 표현했지만, 다양한 기술의 모음이라고 생각하면 된다. 이번 글에서는 서로 다른 용도로 사용되는 마이크로 서비스 Tool에 대해서 살펴 볼 것이다.

운영체제

어플리케이션을 만들때에 가장 중요한 요소 중 하나는 적합한 기반을 설정하는 것이고, 결국 어플리케이션은 운영체제를 기반으로 수행되게 된다. Linux는 이런 운영체제중에 하나이며 가장 일반적으로 사용된다. Linux container를 사용하여 실행 환경 및 보안, 네트워킹, 스토리지와 같은 부분을 조절할 수 있다.

프로그래밍 언어

마이크로 서비스의 주요 장점은 다른 언어와 기술을 사용할 수 있다는 점이다. 따라서 개발자는 자유롭게 기술 스택을 선택하고 어플리케이션을 개발 할 수 있다. 그러나 현재 시점에서 가장 많이 사용되는 언어는 Java기반의 Spring Boot이다.

Spring Boot

Spring Boot는 단 몇줄의 코드로 REST기반의 마이크로 서비스 개발을 단순화 한다.

  • 어플리케이션 개발을 빨리 시작하기 위해 일련의 자동 구성 기능을 제공
  • WAR 파일의 사용을 피하기 위해 Embedded Container(e.g. Tomcat)을 제공
  • Maven 구성을 단순화하여 개발자의 시간을 줄여줌
  • 개발 및 생산에서 어플리케이션을 모니터링하고 관리하기 위한 API를 제공

API 관리 및 테스트 도구

Postman

Postman은 API테스트를 쉽게 할 수 있도록 도와주는 UI 기반의 툴이다.

  • Postman의 도움으로 인해 RESTful API 리소스 탐색이 매우 쉬워진다. 또한 결과 테스트도 도움이 많이 된다.
  • Postman은 어플리케이션의 개발 사이클과 쉽게 통합된다. (CI에서 활용 가능)
  • 여러 버전의 API를 유지/관리하는 기능을 제공한다.
  • 작성된 전체 Collection을 다른 개발자와 공유할 수 있다. (한명만 작업해두면 재사용이 가능하다는 의미)

API Fortress

API Fortress는 부하 테스트, 상태 모니터링 및 기능 테스트를 자동화하는 Tool이다.

  • 이 도구는 API 관리 플랫폼을 점검하는 용도이다.
  • GUI를 제공하기에 API에 대한 테스트 작성/실행을 쉽게 제공한다.
  • 손쉽게 사용할 수 있도록 기능이 제공되기에 End to End 테스트를 단순화 한다.

메시징

마이크로 서비스는 다른 서비스간 통신이 많기 때문에 Messaging Queue를 사용할 수 있다. 메시징에 사용되는 도구는 아래와 같다.

Apache kafka

Apache Kafka는 LinkedIn에서 처음 개발한 분산 Pub/Sub 메시징 시스템이고 현재 Apache 프로젝트의 일부이다. Kafka는 확장 가능하고 민첩한 장점을 지니고 있다. 데이터 처리 또는 API 호출에 사용할 수 있는 분산 스트림 처리 플랫폼이다.

Apache Kafka의 기능은 아래와 같다.

  • Kafka는 안정적인 성능을 유지하기 위해서 Pub/Sub에 대한 처리량이 높다.
  • 다운 타임 제로 및 데이터 손실 제로를 보장한다.

RabbitMQ

Kafka와 마찬가지로 이 툴을 사용하여 마이크로 서비스를 서로 연결하여 분산 시스템의 문제를 해결 할 수 있다. 각 개별 서비스간에 이벤트를 교환 할 수 있다.

  • 안정성, 지속성, Publisher 확인 및 고가용성과 같은 기능을 제공한다.
  • 여러 메시징 프로토콜을 지원한다.

Orchestration 도구

Kubernetes

Kubernetes는 오픈 소스 컨테이너 관리 도구이다. 컨테이너 관리에는 컨테이너 배포, 컨테이너 확장 및 스케일 제거, 컨테이너 로드 밸런싱등이 포함된다.

관점에 따라서 Kubernetes가 평범하고 중요하지 않다고 느낄 수 있다. 그러나 컨테이너 관리를 위해서는 Kubernetes가 필요하고 컨테이너를 만들기 위해서는 Docker가 필요하다. Kubernetes의 기능은 아래와 같다.

  • Kubernetes를 사용하면 이미지를 다시 작성하지 않고도 어플리케이션 구성을 배포하고 업데이트 할 수 있다.
  • Kubernetes는 서비스 관리 외에도 배치 및 CI 워크로드를 관리하여 실패한 컨테이너를 교체 할 수 도 있다.
  • Kubernetes는 CLI와 대시 보드를 제공한다.
  • Kubernetes를 사용하면 원하는 스토리지 시스템을 마운트 할 수 있다. 로컬 스토리지를 선택하거나 GCP 또는 AWS와 같은 퍼블릭 클라우드 공급자를 선택 혹은 NFS, ISCSI등과 같은 공유 네트워크 스토리지 시스템을 사용할 수 있다.

Istio

Istio는 Kubernetes에서 서비스 배포를 지원한다. 또한 마이크로 서비스 통신에 대한 관리 효율성, 보안 및 안정성을 위한 기능을 제공한다. 이는 Service Mesh 기술에 의해 수행되므로 어플리케이션과 마이크로 서비스 간의 관계 및 상호 작용을 향상 시킬 수 있다.

  • 서비스의 자동 추적, 모니터링 및 로깅을 수행한다.
  • 관리 권한 부여, 인증 및 서비스간 통신 암호화를 통해 서비스를 보호한다.
  • Istio는 서비스간 트래픽 및 API 호출 흐름을 제어한다.
  • 정책을 적용하고 시행한다.

모니터링 도구

어플리케이션이 빌드되면 어플리케이션의 작동을 모니터링하는 것은 매우 중요하다. 어플리케이션을 모니터링하기 위해 아래에 언급된 도구를 사용할 수 있다.

Prometheus

Prometheus는 이상 패턴을 감지하여 추적하고 모니터링 정보를 시각화 할 수 있다.

  • 유연한 Query 언어를 제공한다.
  • 서비스 디스커버리 또는 정적 구성을 통해 대상을 발견
  • 대시 보드 및 그래프를 제공한다.

Logstash

Logstash는 로그를 확인할 수 있는 오픈 소스 도구이다. 이 툴을 사용하면 데이터를 숨기거나 중앙에 집중 시키거나 변환할 수 있다.

  • Logstash는 동시에 여러 가지 공통 소스에서 이벤트를 가져 오는 다양한 입력을 지원한다.
  • 이 툴은 복잡성에 관계없이 데이터를 변환하고 준비하는 것을 목표로 한다.
  • Logstash를 사용하면 전송 데이터를 선택할 수 있다.
  • 200개가 넘는 플러그인이 존재하고 이를 이용하여 원하는대로 파이프 라인을 만들고 구성할 수 있다.

11/05/2019

Netflix내의 마이크로서비스가 데이터를 처리하는 방법 (Gutenberg)

 마이크로서비스 아키텍처에서는 단일 서비스에서 여러 목적지로 데이터 세트를 전파하는 것이 어려울 수 있다.

여기서 말하는 데이터 세트는 서비스 구성, 배치 작업 결과등의 모든 것을 의미 할 수 있다.

이러한 것들은 시간이 지남에 따라 종종 업데이트되어야 하기도 한다.

예를 들어서 Netflix에서는 수많은 A/B 테스트를 실행하고 있고 이런 테스트는 여러 서비스를 걸쳐서 수행되기에 테스트 담당자는 구성을 즉시 조정할 수 있어야 한다. 그리고 문제 발생시 이전 버전으로 롤백을 해야 한다.

다른 예는 머신 러닝 모델의 결과에 대한 배포이다. 머신 러닝 모델의 결과는 여러 팀에서 사용되지만, 모델을 담당하는 팀이 고가용성 서비스에 대한 관심이 높진 않다. 그리고 데이터 결과에 대한 활동들은 여러 팀이 활동하기에 중앙 집중화하는 것에 대해 가치가 있다고 판단된다.

하지만, 인프라 수준의 지원이 없다면 모든 팀은 성공을 위해 자체 솔루션을 구축하게 된다. 데이터 세트의 크기는 작게는 몇 바이트에서 많게는 몇 기가 바이트까지 다양한데 각 팀에서 이런 솔루션을 구축하는 것보다는 작업자가 빠르게 변경할 수 있도록 Tool을 제공하는 것이 중요하다.

Netflix에서는 Gutenberg라는 데이터 세트 Pub/Sub 시스템을 사용한다.

Gutenberg를 사용하면 특정 버전의 데이터 세트를 전파 할 수 있다. 데이터 세트의 각 버전은 변경이 불가능하며 데이터의 전체 뷰를 나타낸다. 이전 버전의 데이터에는 의존하지 않는다.

Gutenberg를 사용하면 Debugging 및 데이터를 이용한 머신 러닝 모델의 재학습과 같은 사용 사례에 이용될 수 있다.

데이터 모델


Gutenberg의 최상위 구조는 “Topic”이다. Publisher는 Topic에 게시하고 Consumer는 Topic을 기반으로 소비한다. Publisher가 게시하면 새롭게 증가된 “Version”이 생성된다. 각 Version에 대해서는 유지 개수 혹은 유지 기간을 설정할 수 있다.

각 Version에는 Meta data(Key/Value)와 데이터 포인터가 포함되어 있고, 데이터 포인터는 게시한 실제 데이터가 저장된 위치를 가리키는 특수 메타 데이터이다. 현재 Gutenberg는 직접 데이터 포인터와 S3 데이터 포인터를 지원하고 있고 직접 데이터 포인터는 일반적으로 데이터가 작을 때(약 1MB미만)에 사용되며 S3는 데이터가 클 때 백업 저장소로 사용된다.

Gutenberg는 지역, 응용 프로그램, 클러스터등 특정 Consumer 집합에 게시 범위를 지정할 수 있는 기능을 제공한다. 단일 클러스터로 데이터 변경 사항을 카나리아 방식으로 변경하거나, 변경 사항을 점진적으로 Roll-out하거나, 데이터 세트를 제한하여 어플리케이션의 서브 세트만 구독할 수 있도록 지원한다. Publisher는 특정 데이터 버전의 게시 범위를 결정하고 이전에 게시된 버전에 범위를 추가할 수 있다. 다시 말해서 최신 버전의 개념이 범위에 따라 달라진다는 의미이다. 두 응용 프로그램은 Publisher가 만든 범위에 따라 서로 다른 버전의 데이터를 최신 버전으로 바라 볼 수 있다. Gutenberg는 최신 버전으로 전파할 대상을 결정하기 전에 Consumer 어플리케이션과 Publishing된 범위를 일치시킨다.

사용 사례

Gutenberg의 사용 사례는 단일 Publisher에서 여러 Consumer에게 다양한 크기의 데이터를 전파하는 것이다. 데이터는 Consumer에 의해 메모리상에 저장되어 클라이언트 코드에 의해 Access되고 원자적으로 교환되는 “전체 Cache”로 사용된다. 이런 사용 사례는 느슨하게 그룹핑하여 구성할 수 있다.

예를 들어서 Cache 구성, 지원되는 장치 유형 ID, 지원되는 지불 방법 및 A/B 테스트 구성등

Gutenburg는 데이터의 Pub/Sub을 추상화하여 Publisher가 Consumer에게 영향을 주지 않고 응용 어플리케이션을 자유롭게 반족 할 수 있게 도와준다. 경우에 따라 Gutenberg의 관리 UI를 통해 Publishing이 수행되므로 팀에서 Publisher 기능을 전혀 관리하지 않아도 된다.

Gutenberg의 또 다른 사용 사례는 Version이 지정된 데이터 저장소이다. 이것은 과거 데이터를 기반으로 모델을 구축하고 훈련하는 과정을 반복하는 머신 러닝 프로그램에 일반적인 케이스이다. Gutenberg를 사용하여 계산 결과를 별개의 버전의 데이터 세트로 저장하고 전파하고 온라인 Use-case에서는 최신 Version의 데이터 세트를 사용하여 실시간 요청을 처리하고 “오프라인” Use-case에서는 동일한 Topic의 히스토리 데이터를 사용할 수 있다.

이런 점을 보면, 다들 이렇게 생각할 수 있다. 그냥 Kafka나 Pub/Sub 구조의 이벤트 솔루션을 사용하면 되지 않나? 중요한 점은 Gutenberg가 이벤트 시스템으로 설계되지 않았고 데이터 버전 관리 및 전파를 위해서 존재한다는 점이다. 업데이트를 요청하면 현재 많은 버전이 있다고 해도 최신 버전으로만 제공된다. 전통적인 Pub/Sub 구조의 이벤트 시스템은 크기가 작고 순서대로 소비되는 메시지에 적합하다. 그러나 Gutenberg는 데이터 세트에 대한 불변의 전체뷰를 게시하고 사용하도록 설계되었다.

아키텍처

Gutenberg는 gRPC 및 REST API가 포함된 서비스와 gRPC API를 사용하는 Java Client Library로 구성되어 있다.


Client

Gutenberg 클라이언트 라이브러리는 구독 관리, S3 업로드/다운로드, Atlas metric 및 Archaius properties 를 사용하여 작업을 처리한다. 서비스 검색에 Eureka를 사용하여 gRPC를 통해 Gutenberg 서비스와 통신한다.

Publishing

Publisher는 API를 사용하여 문자열, 파일 또는 바이트 배열을 게시한다. 데이터 크기에 따라 데이터가 직접 데이터 포인터로 게시되거나 S3에 업로드 된 후 S3 데이터 포인터로 게시 될 수 있다. 클라이언트는 요청자를 대신하여 Payload를 S3에 업로드하거나 S3에 이미 존재하는 Payload에 대한 메타 데이터만 게시 할 수 있다.

직접 데이터 포인터는 자동으로 복제된다. S3에 게시된 데이터는 기본적으로 게시자가 여러 지역에 업로드 하지만 요청자가 구성 할 수 도 있다.

구독 관리

클라이언트 라이브러리는 Consumer를 위한 구독 관리 기능을 제공한다. 이 기능을 통해 사용자는 특정 Topic에 대한 구독을 작성할 수 있고, 라이브러리는 이를 기반으로 데이터를 검색한다. 구독은 Polling Model로 작동되며 30초마다 서비스에 새 업데이트를 요청하여 마지막으로 전달 받은 버전을 제공한다. 문제 발생시 재시도하는 로직은 기본으로 탑재되어 있다.

Consumption APIs

Gutenberg는 저수준 gRPC API를 Wrapping하여 추가적인 기능을 제공하는 고수준 Client API를 제공한다. 예를 들어서 특정 Topic과 Version에 대한 데이터를 다운로드한다고 할때, Netflix Hollow에 연결된 구성 요소를 광범위하게 사용할 수 있다. 또는 특정 시간에 Topic의 최신 버전을 얻는 방법도 존재한다.

Client 탄력성 및 관찰성

Gutenberg는 Comsuming 서비스를 성공적으로 하도록 설계 되었다. 이를 염두해두고 Client Library는 Gutenberg 서비스와 통신 할 수 없는 경우에 대해 대비하여 구현되었다. HTTP 요청 재시도 횟수가 소진 된 후에 Client는 S3에서 Topic에 대한 fallback cache를 다운로드 하고 이를 기반으로 작동한다. 해당 Cache에는 업데이트를 적용해야 하는지 여부와 Meta 데이터 자체 또는 S3에서 데이터를 가져와야 하는 위치를 결정하는데 필요한 모든 정보가 포함되어 있다. 이를 통해 Client는 서비스를 사용하지 않고 데이터를 Fetch할 수 있다.

Client Library 제공의 이점중 하나는 인프라 전체의 문제 또는 특정 응용 프로그램의 문제를 경고하는데 사용할 수 있는 Metric 제공하는 기능이다. 이런 측정 항목은 Gutenberg에서 게시 및 전파를 모니터링하고 광범위한 문제가 발생했을 경우 이를 경고하는데 사용된다. 또한 일부 클라이언트는 이런 측정 항목을 사용하여 개별 게시 실패 또는 특정 Topic 사용 실패와 같은 오류에 대해서도 알려준다.

Server

Gutenberg 서비스는 gRPC 및 REST End-point를 공개하는 Governator/Tomcat 어플리케이션이다. 지속성을 위해서 글로벌하게 복제된 Cassandra Cluster를 사용아여 모든 지역에 게시 메타 데이터를 전파한다. Consumer 요청을 처리하는 인스턴스는 게시 요청을 처리하는 인스턴스와 별도로 확정된다. 일반적으로 게시 요청보다 Consuming 요청이 약 1000배 더 많기에 Publishing을 Consuming으로 부터 격리시킨다. 그 이유는 갑자기 Publishing이 급증해도 Consuming에 영향을 미치지 않기 위함이고 반대도 마찬가지이다.

Consumer 요청 클러스터의 각 인스턴스는 자체 메모리의 최신 게시에 대한 Cache를 유지 관리하여 몇 초마다 Cassandra에서 새롭게 갱신된다. 이는 트래픽을 Cassandra 클러스터로 전달하지 않고 클라이언트에서 오는 대량의 Polling 요청을 처리하기 위함이다.

여러 지역의 S3 Bucket에 데이터가 게시 된 경우에는 서버는 클라이언트의 위치에 따라 다운로드 할 클라이언트로 다시 보낼 Bucket을 결정한다. 이 경우 가장 가까운 Region에서 Bucket을 클라이언트에 제공하고 Region이 중단 된 경우 클라이언트가 다른 Region으로 fallback되도록 한다.

구독 데이터를 Consumer에게 반환하기 전에 Gutenburg는 데이터에 대한 일관성 검사를 선행한다. 검사가 실패하고 Polling 클라이언트가 일부 데이터를 사용한 경우 서비스는 아무것도 리턴하지 않으므로 사실상 사용 가능한 업데이트가 없음을 의미한다. Polling 클라이언트가 데이터를 사용하지 않은 경우에는 히스토리를 조회하고 일관성 검사를 통해 최신 데이터를 리턴한다. 클라이언트가 새로운 데이터를 Polling할 때 가장 최근에 게시된 버전과 관련된 메타 데이터가 복제된 Cassandra 계층에서 복제 지연이 발생하기 때문이다. 그리고 데이터를 가져올때 실패할 경우를 대비해 서버에서는 일관성 검사를 실행한다.

Data Resilient

Pinning

어플리케이션의 개발 환경에서는 배포가 잘못되거나 배포를 Rollback하는 정책이 필요하다. 데이터 중심의 아키텍처는 시간이 지남에 따라서 변경되는 데이터에 의해 작동되기에 이 부분은 매우 까다롭다.

Guternberg에서는 문제가 발생하면 마지막 안정버전의 데이터로 Rollback할 수 있는 방법이 필요하다. 이를 제공하기 위해서 Gutenberg는 Topic을 특정 버전에 고정하는 기능을 제공한다.

Pin은 최신 버전의 데이터를 무시하고 클라이언트가 해당 버전으로 Update하도록 도와준다.

따라서 관리자가 마지막의 안정버전을 모르더라도 빠르게 처리할 수 있다.

Incremental Rollout

새로운 코드를 배포할때는 카나리아 혹은 점진적으로 Rollout하는 방식으로 수행한다.

Gutenberg가 제공하는 기능중에 SPinnaker 파이프라인을 통해 데이터 게시를 Rollout라는 것을 제공한다. 특정 Topic의 경우 사용자는 자신이 게시 할 범위에 지연 시간을 구성하게 된다. 그리고 해당 Topic에 게시하게 되면 파이프 라인이 시작되어 동일한 데이터 버전이 각 범위에 점차적으로 게시되게 된다. 사용자는 파이프라인과 상호 작용할 수 있다.

Scale

Gutenberg는 지난 3년간 Netflix에서 사용되고 있고, 수만 가지의 Topic을 Production에 저장하고 있다. 이 중에 약 1/4이 지난 6개월 동안 한번 이상은 Publishing되었다. Topic은 1분에 수십번에서 몇달간 한번까지 다양하게 게시되었으며, 평균적으로 약 12시간 간격으로 초당 약 1~2번의 게시가 가능하다.

24시간 동안 적어도 한개의 Topic에 가입된 노드의 수는 6자리 미만이고, 이 노드중 하나가 구독하는 최대 Topic수는 200개이다.

향후 작업 계획

Polyglot 지원 (현재는 Java만 지원하지만, Node.js 및 Python을 지원할 계획을 가지고 있다.)

암호화 지원 (민감한 데이터의 경우 암호화 및 암호 해독 기능을 제공하여 사용 될 수 있도록 준비중이다.)

Topic 정리 (Topic을 게시하거나 사용하지 않는 사람이 있어도 명시적으로 삭제하지 않는한 Topic이 계속 유지되기에 Elasticsearch에서 색인화 작업을 거쳐서 Topic을 정리하는 시스템을 구축할 계획)

References:

  • https://medium.com/netflix-techblog/how-netflix-microservices-tackle-dataset-pub-sub-4a068adcc9a


10/09/2019

 마이크로 서비스(MSA) 전환시 알아야 할 것

어떤 서비스를 만들때에 Monolithic으로 만들어야 할지? Monolithic으로 만들고 Microservices로 구성해야 할지? 아니면 처음부터 Microservices로 구성해야 하는지에 대한 고민이 생긴다.

Microservices는 최근 급속히 발전하는 많은 기업이 소프트웨어 아키텍처로 이동할 것을 고려하고 있다.

Microservices 또는 Serverless로의 이동은 잘 만들면 금융, 소매, 마케팅, 데이터 분석 및 기타 여러 산업에서 효율성을 가져 올 수 있다.


위 그래프는 2017년에 도입되었거나 2018년도에 도입해야 하는 최우선 기술들을 표현한 그래프이다.

제품이나 서비스가 잘못 설계되었을 경우, Microservices를 적용한다고 하여 품질이 향상되지는 않는다. (그 이유는 똥을 분리해봐야 똥이기 때문이다.)

마이크로서비스를 적용해야 하는 경우

위의 똥 그림 때문이라도 이글을 읽는 당신은 마이크로서비스에 대해서 이해를 해야 한다.

Microservices 제품은 API를 통해 상호 작용하는 형태의 분리된 구성으로 소프트웨어를 설계하는 아키텍처에 대한 방법이다.

  • 기능을 분리하는 동안, 여전히 일부 중복되는 기능과 코드가 존재한다.
  • 주요 기능을 수행하는 것 이외에, 마이크로서비스는 API를 통해 다른 모듈과의 연결을 지원한다.
  • 마이크로서비스는 개별적으로 개발이 될 수 있지만, 상호 의존성에 대한 부분이 존재하고 이는 출시 전에 테스트가 심도있게 되어야 한다. 특정 마이크로서비스의 일부 기능은 다른 마이크로서비스에서 사용할 수 있기에 특정 서비스가 업데이트되면 다른 서비스에 영향을 줄 수 있기 때문이다.

기술적으로 분리를 하더라도 마이크로 서비스는 여전히 상호간 의존하기 때문에, 이 의존성을 낮추기 위해서는 몇가지 기능을 복제해야 하는 상황이 발생할 수 있다.

이런 상황에 대한 부분은 아래와 같다.

  • 제품의 일부가 개별적으로 재부팅 할 수 있어야 하며, 이는 복원력을 향상 시킬 수 있다.
  • 많은 기능이 의무적인 상호 작용의 수를 줄이기 위해서 분리 되거나 하여 개발의 복잡성을 줄일 수 있어야 한다.
  • 새로운 기능의 시장 출시 시간을 단축할 수 있어야 한다.

개발시에 위와 관련된 고민 사항들도 있지만, 운영의 복잡성도 상당하다는 점을 알고 있어야 한다.

즉, 기존의 Monolithic을 분할하게되면 운영의 복잡성을 증가한다는 것을 인지해야 한다.

그리고, 해당 기업의 IT부서가 이러한 시스템을 설계, 구현 및 유지 관리 할 수 있는 전문 지식을 가지고 있어야 한다.

만약, 이런 부분들이 고려되어 있지 않다면 마이크로서비스를 전환하는 것이 불행한 작업이 될 것이다.