마이크로 서비스에서 각 서비스에 대한 단일 데이터베이스 또는 단일 데이터베이스 인스턴스입니까?


50

마이크로 서비스 아키텍처의 각 서비스에는 자체 데이터베이스가 있어야한다는 것을 이해합니다. 그러나 자체 데이터베이스를 가지고 있다는 것은 실제로 동일한 데이터베이스 인스턴스 내에 다른 데이터베이스가 있거나 문자 그대로 다른 데이터베이스 인스턴스가 있다는 의미입니까?

이것은 데이터베이스 공유를 의미하는 것이 아니라 데이터베이스 인스턴스가 아닙니다.

예를 들어, AWS를 사용 중이고 3 개의 서비스가있는 경우 단일 RDS 인스턴스에서 각 서비스에 대해 3 개의 데이터베이스를 생성합니까 아니면 3 개의 각 서비스에서 독립적으로 사용하는 데이터베이스를 포함하는 3 개의 RDS 인스턴스를 생성합니까?

단일 RDS 인스턴스에서 여러 데이터베이스를 사용하는 것이 더 좋은 아이디어라면 다음과 같은 이유로 독립 서비스를 갖는 목적을 상실하게 될 것입니다.

  1. RDS 인스턴스의 리소스는 서비스간에 공유됩니다. 특정 시간에 데이터베이스 사용량이 많은 서비스 A가 다른 데이터베이스를 사용하지만 동일한 RDS 인스턴스를 사용하는 서비스 B에 영향을 줍니까?

  2. 모든 서비스는 해당 RDS 인스턴스의 데이터베이스 버전에 따라 다릅니다.


8
특정 요구 사항에 가장 잘 맞는 것입니다.
Robert Harvey

1
나는 자신을 '마이크로 서비스'전문가라고 부를지 확신하지 못하지만 어떤 방식 으로든 설정 및 데이터베이스를 가질 수 있습니다. 한 서비스에서 읽고 다른 서비스에서 쓰는 db를 가질 수 있습니다. 또는 전체 시스템에 대해 1 db (또는 기술적으로 덜) 만 가질 수 있습니다.
마크 로저스

다음은이 문제에 좋은 읽기는 다음과 같습니다 plainoldobjects.com/2015/09/02/...
RandomUs1r

'단일 책임 원칙'에 대해 읽어보십시오. 다른 마이크로 서비스가 사용하는 '데이터베이스 마이크로 서비스'구현에 대해 생각해 보셨습니까?
ChuckCottrill 2018 년

답변:


20

이는 확장 성 요구 사항과 단일 결과를 제공하기 위해 마이크로 서비스 인스턴스가 어떻게 협력해야하는지에 따라 다릅니다. 트레이드 오프가 무엇인지 아는 것이 도움이됩니다.

하나의 데이터베이스에 모든 것을 유지

  • 더 쉬운 구성
  • 다른 서비스 인스턴스와의 조정 또는 통신이 필요하지 않습니다.
  • 전체 데이터 세트를보다 쉽게 ​​검색
  • 데이터베이스 성능에 의해 제한되는 시스템 성능

데이터베이스를 별도로 유지

  • 요청에 대한 전체 답변은 마이크로 서비스 인스턴스에 분산 될 수 있습니다.
  • 이 경우 요청을 해결하기 위해 통신 및 협상이 향상되었습니다.
  • 해당 마이크로 서비스 노드를 잃어 버렸을 때 데이터 처리
  • 구성 복잡성 증가

해결하려는 문제는 무엇입니까?

경우에 따라 임시 데이터 만 걱정할 수도 있습니다. 데이터베이스가 다운되면 큰 문제가 아닙니다. 이 경우 데이터베이스가 필요하지 않을 수도 있습니다. 모든 것을 메모리에 보관하고 엄청나게 빠르게 만드십시오. 가장 쉬운 솔루션입니다.

다른 경우에는 데이터 무결성이 필요하지만 데이터베이스는 보유한 노드 수에 따라 용량을 확장 할 수 있습니다. 이 경우 단일 데이터베이스로 충분할 수 있으며 데이터베이스의 응답 성을 독립적으로 관리하는 것이 정답입니다.

그 사이에는 여러 가지 경우가 있습니다. 예를 들어, 지역별로 고유 한 데이터베이스가있을 수 있으므로 다른 지역에있는 각 서비스 인스턴스마다 별도의 데이터베이스가 있습니다. 일반적으로 샤딩 데이터베이스는 여러 지역에서 잘 수행되지 않으므로 데이터를 조금 현지화하고 조정을 직접 제어 할 수 있습니다.

교리와 현실

마이크로 서비스에 대한 많은 기사와 이들이 어떻게 모듈화되어야하는지 읽었습니다. 권장 사항은 프런트 엔드, 마이크로 서비스 및 데이터 계층을 전체 단위로 유지하는 것부터 모든 인스턴스에 대한 데이터베이스 및 / 또는 프런트 엔드 코드 공유에 이르기까지 다양합니다. 일반적으로 격리가 많을수록 확장 성이 가장 크지 만 복잡성이 증가합니다.

마이크로 서비스가 계산량이 많은 경우 데이터베이스 나 프런트 엔드 코드를 공유해도이 접근 방식이 손상되거나 방해받지 않으면 서 필요에 따라 마이크로 서비스 수를 확장 할 수 있습니다.

실제로 프로젝트의 특정 요구는 적시에 작업을 수행하고 측정중인 시스템 부하를 처리하기 위해 다른 타협이 필요합니다 (약간 더). 완전히 격리 된 프런트 엔드, 마이크로 서버 및 데이터 계층 트리오를 높은 목표로 생각하십시오. 시스템에 대한 수요가 많을수록 해당 목표에 더 근접 할 수 있습니다. 우리는 모두가 아니며 [insert name of highly successful web entity here], 그들이 지금있는 곳에서 시작하지 않았습니다. 때로는 완벽하지 않은 상황에서 시작하여 그에 만족해야 할 때가 있습니다.


71

동일한 종류의 DB 시스템 및 버전을 사용할 수있는 서비스가 있다고 가정 할 때 다른 데이터베이스 또는 db 인스턴스를 사용하는 경우 디자인 타임에 결정하지 않아도됩니다. 대신 배포시 간단하게 구성 할 수있는 결정을 내릴 수 있어야합니다. 다른 서비스 데이터베이스가 호스팅되는 장소에 관계없이 서비스를 설계하십시오.

작동 중에 하나의 인스턴스로 시작할 수 있으며 시스템이 제대로 작동하면 그대로 두십시오. 그러나 한 인스턴스의 다른 데이터베이스가 너무 많은 리소스를 공유하기 때문에 시스템에 맞게 확장 할 수없는 경우 항상 다른 인스턴스를 사용할 수있는 옵션이 항상 있습니다.

따라서 서비스 중 두 개가 일부 리소스를 공유하게한다고해서 서비스가 마이크로 서비스 아키텍처를 위반하지 않습니다. 리소스 공유가 필수가되면 서비스를 위반하는 것입니다.


이런 종류의 소리는 조기 최적화와 같습니다. 소비 된 리소스가 추가 인스턴스를 가치가 없다면 어떻게해야합니까? 그런 다음 유연성을 구축하는 데 시간을 낭비했습니다.
reggaeguitar

5
@reggaeguitar : 이것에 대한 비용은 일반적으로 무시할만한 수준이어야합니다. 실제로 마이크로 서비스 아키텍처의 경우 각 서비스의 db 위치를 개별적으로 구성 할 수있는 것보다 다른 서비스간에 데이터베이스 구성을 중앙 집중화하는 것이 더 많은 노력 일 수 있습니다. 더욱이, 마이크로 서비스 아키텍처의 요점은 높은 확장 성이며, 필요하지 않다면 마이크로 서비스를 먼저 결정해서는 안됩니다.
Doc Brown

1
@DocBrown 응답 해 주셔서 감사합니다!
reggaeguitar

13

중요하지 않습니다.

이론적으로 중요 할 수있는 유일한 시나리오는 한 서비스가 다른 버전의 데이터베이스로 마이그레이션해야하는 경우입니다. 그러나 시작부터 별도의 인스턴스를 갖는 것과 공유 인스턴스에서 별도의 서비스로 하나의 서비스를 마이그레이션하는 것 사이에는 실질적인 차이가 없습니다. 실제로이 시나리오 때문에 별도의 인스턴스를 갖는 것이 YAGNI의 예라고 말하고 싶습니다.


1
특정 서비스가 단일 RDS 인스턴스에서 사용량이 많다고 가정하면 해당 인스턴스의 리소스를 소모하고 동일한 RDS 인스턴스를 사용하는 다른 서비스에 영향을 미치게됩니까?
크세논

1
@xenon : 예,하지만 시스템 아키텍처를 변경하는 것이 아니라 튜닝, 하드웨어 또는 클러스터링을 통한 RDS 성능 개선에 대해 생각해야하는 이유입니다. 해당 서비스가 다른 서비스의 용량을 남겨두면 곧 용량이 부족합니다. 그 자체로. 과부하 된 서비스가 다른 서비스에 영향을 미치지 않아야한다는 특별한 요구 사항이있을 수 있다고 생각합니다. 실제로 일부 RDS는 사용자별로 리소스 제한을 정의하여 단일 인스턴스에서이를 허용 할 수 있습니다.
Michael Borgwardt 2016 년

중요한 시나리오는 마이크로 서비스 인스턴스 가 자체 상태를 갖는 경우 입니다. 그런 다음 성능 병목 현상이 발생할 수있는 자체 인스턴스 db 로 배포해야합니다.
Ewan

3

RDS 인스턴스는 단일 상자입니다. 단일 인스턴스에 여러 데이터베이스가있는 경우 CPU / 메모리 등을 공유합니다.

마이크로 서비스 성능이 데이터베이스 성능에 의해 제한되는 경우 : 각각 다른 데이터베이스를 사용하지만 각 데이터베이스가 동일한 RDS 인스턴스에있는 여러 개의 마이크로 서비스 복사본을 배포합니다. 무의미합니다 * (장애 조치 제외). 마이크로 서비스 클러스터는 단일 마이크로 서비스와 동일한 속도로 실행됩니다

그러나 데이터베이스 성능에 묶인 마이크로 서비스는 드문 일이라고 말하고 싶습니다.

일반적으로 마이크로 서비스는 db에서 데이터를 가져 와서 일부 논리를 수행하고 일부 정보를 데이터베이스에 다시 씁니다. 성능 병목 현상은 선택 및 / 또는 삽입이 아닌 논리 입니다.

이 경우 모든 마이크로 서비스 인스턴스에서 동일한 데이터베이스를 공유 할 수 있습니다


논리가 데이터베이스가 아닌 병목 현상이라는 주장에 의문을 제기해야합니다. 내 경험상 성능 향상을 찾을 수 있는 가장 가능성이 높은 곳은 데이터베이스입니다.
RubberDuck

그렇습니다. 그러나 이러한 성능 향상은 로직 db에서 서비스로 이동시킴으로써 달성됩니다 . 당신이 그 일을하면, THEN 로직은 병목
이완

1
일반적으로 아닙니다. 이러한 개선 사항은 인덱스 및 쿼리 조정에서 비롯됩니다.
RubberDuck

글쎄, 그건 내 경험에서 특이한 경우에 해당합니다. 일반적으로 이러한 개선의 여지가 없지만 실제로 나쁜 물건을 제거한 후에도 데이터베이스는 여전히 제한 요소입니다.
Ewan

1

데이터베이스를 서비스 전용으로 유지하는 목표는 캡슐화입니다. 마이크로 서비스는 시스템의 다른 서비스가 공용 인터페이스를 통해 사용할 블랙 박스입니다.

이 캡슐화가 작동하는 두 가지 평면이 있습니다.

  • 첫 번째는 응용 프로그램 수준에서 논리적입니다. 서비스는 시스템에서 일부 비즈니스 오브젝트를 소유하며 이러한 오브젝트에 대한 상태를 유지해야합니다. 어떤 것을 특정 데이터베이스가 이러한 비즈니스 오브젝트를 백업 단지 구현 세부입니다. 별도의 데이터베이스를 유지하면 다른 서비스가 구현에 대한 백도어 액세스를 방지하여 공용 인터페이스를 대신 사용할 수 있습니다. 여기서의 목표는 깔끔한 아키텍처와 훈련 된 프로그래밍입니다. 서비스가 연결 정보를 찾을 수 있도록 올바른 연결 세부 정보를 가지고 있다면 데이터베이스 수준이 정확히 어디에 있는지는이 수준과 관련이 없습니다.

  • 두 번째 수준은 작동입니다. 디자인이 완벽한 블랙 박스 라하더라도 단일 시스템에 배치 된 다른 작업은 리소스를 놓고 경쟁 할 수 있습니다. 이것은 별도의 논리 데이터베이스를 별도의 시스템에 두는 좋은 이유입니다. 다른 답변에서 알 수 있듯이 요구 사항이 까다 롭지 않고 예산이 부족한 경우 단일 시스템에서의 배치에 대한 실용적인 주장입니다. 그러나 항상 그렇듯이 트레이드 오프 :이 설정은 시스템이 성장함에 따라 더 많은 베이비 시터가 필요할 수 있습니다. 예산이 허락한다면, 나는 항상 하나의 큰 컴퓨터를 공유하는 것보다 두 개의 작업을 수행하기 위해 두 개의 별도의 작은 기계를 선호합니다.


1

나는 이것이 더 이론적으로 도움이 될 것이라고 생각합니다. 마이크로 서비스의 동기 부여 아이디어 중 하나는 아무것도없는 메시지 전달 프로세스입니다. 마이크로 서비스는 액터 모델의 액터와 같습니다. 즉, 각 프로세스는 자체 로컬 상태를 유지하며 한 프로세스가 다른 프로세스의 상태에 액세스하는 유일한 방법은 메시지를 보내는 것입니다 (그리고 다른 프로세스도 메시지를 좋아하지만 응답 할 수 있음). "모든 마이크로 서비스는 자체 데이터베이스를 가지고있다"는 것은 프로세스의 상태 (즉, 마이크로 서비스)가 로컬프라이빗이라는 것을 의미 합니다. 대부분 "데이터베이스"를 함께 배치 해야 함을 나타냅니다."데이터베이스"는 마이크로 서비스와 함께 마이크로 서비스와 동일한 논리 노드에 저장되고 실행되어야합니다. 마이크로 서비스의 서로 다른 "인스턴스"는 별도의 프로세스이므로 각각 자체 "데이터베이스"를 가져야합니다.

마이크로 서비스 또는 마이크로 서비스 인스턴스간에 공유되는 글로벌 데이터베이스 또는 데이터베이스는 이러한 관점에서 공유 상태를 구성합니다. 마이크로 서비스 관점에서이를 처리하는 "적절한"방법은 공유 데이터베이스가 "데이터베이스"마이크로 서비스에 의해 조정되는 것입니다. 데이터베이스의 내용에 대해 알고 싶은 다른 마이크로 서비스는 해당 "데이터베이스 마이크로 서비스"에 메시지를 보냅니다. 일반적으로 원래 마이크로 서비스에 대한 로컬 상태 (마이크로 서비스 인스턴스 "데이터베이스")가 필요하지 않습니다! 변화하는 것은 그 지방 상태가 나타내는 것입니다. "User Sally는 관리자입니다"를 저장하는 대신 "데이터베이스 마이크로 서비스는 'User Sally는 관리자입니다'라는 메시지를 5 분 전에 저장했습니다." 다시 말해, 다른 마이크로 서비스 상태에 대해

이것의 장점은 각각의 마이크로 서비스가 독립적이라는 것입니다. 이로 인해 마이크로 서비스가 원자 단위의 고장이됩니다. 부분적으로 기능적인 상태의 마이크로 서비스에 대해 걱정할 필요가 없습니다. 물론 문제는 마이크로 서비스 네트워크로 옮겨졌다. 마이크로 서비스가 다른 마이크로 서비스에 접속할 수 없어서 원하는 기능을 수행하지 못할 수 있습니다. 그러나, 이점은 마이크로 서비스가 잘 정의 된 상태에 있고 예를 들어 오래된 신념을 해결함으로써 성능이 저하되거나 제한된 서비스를 제공 할 수 있다는 것입니다. 단점은 시스템 전체의 일관된 스냅 샷을 얻는 것이 매우 어렵고, 많은 (과도의) 중복 및 복제가있을 수 있다는 것입니다.

물론 오라클의 인스턴스를 모든 Docker 컨테이너에 고정시키는 것은 아닙니다. 첫째, 모든 마이크로 서비스에 "데이터베이스"가 필요한 것은 아닙니다. 일부 프로세스는 올바르게 작동하기 위해 지속적 상태가 필요하지 않습니다. 예를 들어, 두 프로토콜 간을 변환하는 마이크로 서비스에는 영구 상태가 반드시 필요한 것은 아닙니다. 지속 상태가 필요한 경우 "데이터베이스"라는 단어는 "지속적 상태"를 나타내는 단어 일뿐입니다. JSON이 있거나 Sqlite 데이터베이스 또는 로컬로 실행중인 Oracle의 사본 또는 로컬의 다른 방법이있는 파일 일 수 있습니다지속적으로 데이터 저장. "데이터베이스"가 로컬이 아닌 경우 순수한 마이크로 서비스 관점에서 별도의 마이크로 서비스처럼 취급해야합니다. 이를 위해 RDS 인스턴스를 마이크로 서비스의 "데이터베이스"로 만드는 것은 결코 의미가 없습니다. 다시, 관점은 "자체 RDS 데이터베이스가있는 다수의 마이크로 서비스"가 아니라 " RDS 데이터베이스 와 통신하는 다수의 마이크로 서비스 "입니다. 이 시점에서 데이터가 동일한 데이터베이스 인스턴스에 저장되는지 여부는 차이가 없습니다.

실제로 마이크로 서비스 아키텍처는 엄청난 복잡성을 추가합니다 . 이 복잡성은 부분 실패를 심각하게 처리하는 가격 일뿐입니다. 많은 사람들에게 혜택을받을 가치가없는 것은 과잉입니다. 가장 유익한 방식으로 시스템을 자유롭게 설계해야합니다. 단순성과 효율성에 대한 우려가 순수한 마이크로 서비스 아키텍처와의 편차로 이어질 가능성이 높습니다. 비용은 서비스 간의 보이지 않는 상호 작용 및 원하는대로 자유롭게 배포 및 확장 할 수있는 제한과 같은 고유 한 복잡성을 야기하는 추가 커플 링입니다.


"다른 마이크로 서비스에 접속할 수 없기 때문입니다." -마이크로 서비스가 다른 마이크로 서비스와 접촉해서는 안된다고 생각 했습니까?
마크
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.