다른 마이크로 서비스가 "소유"한 데이터베이스에서 데이터를 읽는 것이 왜 그렇게 나쁜가


64

최근 마이크로 서비스 아키텍처에서이 훌륭한 기사를 읽었습니다. http://www.infoq.com/articles/microservices-intro

Amazon에 웹 페이지를로드하면 100 개 이상의 마이크로 서비스가 해당 페이지를 제공하기 위해 협력한다는 내용입니다.

이 기사에서는 마이크로 서비스 간의 모든 통신이 API를 통해서만 이루어질 수 있다고 설명합니다. 내 질문은 모든 데이터베이스 쓰기가 API를 통해서만 이루어질 수 있다고 말하는 것이 좋지 않은 이유입니다. 그러나 다양한 마이크로 서비스의 데이터베이스에서 직접 읽을 수 있습니다. 예를 들어 마이크로 서비스 외부에서는 소수의 데이터베이스 뷰만 액세스 할 수 있으므로 마이크로 서비스를 유지 관리하는 팀은 이러한 뷰를 그대로 유지하는 한 마이크로 서비스의 데이터베이스 구조를 원하는만큼 변경할 수 있음을 알 수 있습니다. 결핍, 필요.

여기에 뭔가 빠졌습니까? API를 통해서만 데이터를 읽어야하는 다른 이유가 있습니까?

말할 필요도없이, 우리 회사는 아마존보다 훨씬 작으며 (항상 그렇게 될 것입니다) 우리가 가질 수있는 최대 사용자 수는 약 5 백만입니다.


답변에 언급되지 않은 한 가지 더 일반적인 요소는 데이터베이스에 쓸 때 로컬 캐싱, 심지어 간단한 O / R 매핑조차도 데이터베이스에 즉시 액세스 할 때 오래된 데이터를 생성 할 수 있다는 것입니다. 속도 이유로 µservice API를 우회하는 것을 고려한다면 µservice 아키텍처를 너무 많이 사용했을 수 있습니다.
Joop Eggen

데이터베이스 읽기를 허용하면 데이터베이스의 모든 세부 사항이 공용 API의 일부가됩니다. 그런 복잡한 API에서 호환성을 유지하고 싶지 않습니다.
Patrick

그러나이 경우 뷰가 최소한 의미 상 목적을 위해 단순히 API의 일부가되지 않습니까? API를 호출하는 대상과 유지 관리해야 할 대상의 문제 일뿐입니다. 일반적으로 데이터베이스 위의 계층은 일관성을 유지하기가 더 쉽습니다.
lc.

나는 그 견해가 단순히 API의 한 형태 일 것이라는 데 동의합니다. 나는이 질문에 대답하는 대부분의 사람들이 뷰를 추상화 수준으로 사용하는 것에 대한 내 생각을 읽지 못한다고 생각합니다. 데이터베이스 기술을 변경했다면 견해를 그대로 유지하는 것이 큰 과제이지만, 향후 5 년간 데이터베이스 기술을 변경할 필요는 없다고 생각합니다. 또한 5 밀 사용자에게는 성능에 문제가 없습니다. 따라서 크기가 주어지면이 해결책에 갈 것입니다. 여기의 대답은 내가 고통의 세계로 곧장 가고 있음을 나타내는 것처럼 보입니다.
David

답변:


69

데이터베이스는 정보 숨기기에 그다지 좋지 않습니다. 실제로 정보를 공개하는 것이기 때문에 그럴듯합니다. 그러나 이것은 캡슐화와 관련하여 큰 도구입니다. 캡슐화를 원하는 이유는 무엇입니까?

시나리오 : 몇 가지 구성 요소를 RDBMS에 직접 연결하면 특정 구성 요소 중 하나가 데이터베이스를 비정규 화하려는 성능 병목 현상이되는 것을 볼 수 있지만 다른 모든 구성 요소가 영향을받을 수는 없습니다. RDBMS보다 문서 저장소 나 그래프 데이터베이스를 사용하는 것이 더 나을 수도 있습니다. 데이터가 작은 API로 캡슐화되어 있으면 원하는 방식으로 해당 API를 다시 구현할 수있는 현실적인 기회가 있습니다. 캐시 레이어를 투명하게 삽입 할 수 있습니다.

애플리케이션 계층에서 직접 스토리지 계층으로 허비하는 것은 의존성 역전 원리가 제안하는 것과 정반대입니다 .


1
이것은 좋은 지적입니다! 걱정하지 않는 한 가지는 Postgres가 이제 문서 저장소와 RDBMS를 모두 지원한다는 것입니다 ( loop.com/articles/2014-09-30-postgresql-nosql 제외 ). 당신의 요점은 여전히 ​​유효합니다.
David

3
도구가 무언가를 할 수 있다고해서 @David를 덜 걱정해서는 안됩니다. 그것은 어느 정도 분리의 요점입니다. 사용자가 보는 것을 변경하지 않고 API 뒤의 데이터를 완전히 변경할 수 있습니다. 클라이언트가 보는 것과 동일한 한 백엔드를 원하는만큼 변경할 수 있습니다.
Ben

1
@David 이것은 흥미로운 뉴스이지만, 내가 설명한 시나리오와는 관련이 없습니다. DB 스키마를 관계형 문서에서 문서 기반 스키마로 변경하면 스키마에 따라 모든 스키마 스키마에 동일한 영향을 미칩니다. 모든 쿼리를 다시 작성해야합니다. 또한 이러한 모든 변경 사항을 한 번에 배포해야하는 악몽도 있으므로 시스템간에 구성 요소 간의 호환성이 유지됩니다.
back2dos

1
@David : 잘 정의 된 몇 가지 뷰에 대한 액세스를 제한한다는 것은 또 다른 이점과 함께 다른 API를 빌드하는 것을 의미합니다. 보기 만 가능한 한 읽기 전용 액세스로 제한됩니다. 그리고 구성 요소가 서비스 API와 뷰 API 모두에 의존하는 것은 매우 취약합니다. 따라서 구성 요소를 뷰에 의존하게 만드는 경우 읽기 전용 또는 유지 관리가 높은 것으로 미리 결정했습니다. 여기 기술 부채가 있습니다. 또한 데이터베이스에서 허용하지 않는 방식으로 수평 파티셔닝을 추가 할 수 있습니다.
back2dos

2
@David : 장기적으로는 코드를 작성하는 것이 얼마나 쉬운 지보다 코드를 변경하는 것이 더 중요합니다. 아키텍처는 "그러한 방식으로 코드를 작성해서는 안된다"고 말하지 않으며, "만약 그렇게하면 코드를 유지하려고한다면 끔찍한 악몽을 겪게 될 것"이라고 말합니다. 프로토 타입을 말하는 경우 유지 관리가 필요하지 않습니다. 어서 프로토 타입은 가능한 한 쉽게 포인트를 증명해야합니다. 그러나 Sisyphean의 자기 유도 고문으로 진행하지 않고 모든 입증 된 포인트를 시스템에 통합하려고하면 여분의 마일을 얻는 것이 좋습니다.
back2dos

55

마이크로 서비스에서 더 중요하고 중요한 것은 API 또는 데이터베이스 스키마입니까? API는 다른 세계와의 계약이기 때문입니다. 데이터베이스 스키마는 단순히 서비스가 관리하는 데이터를 저장하는 편리한 방법이며 마이크로 서비스의 성능을 최적화하는 방식으로 구성되기를 바랍니다. 개발 팀은 언제든지 해당 스키마를 자유롭게 재구성하거나 완전히 다른 데이터 저장소 솔루션으로 전환 할 수 있어야합니다. 나머지 세계는 신경 쓰지 않아야합니다. API는 계약이기 때문에 나머지 세계는 API가 변경 될 때주의를 기울입니다.

이제 데이터베이스를 엿 보면

  • 스키마에 원하지 않는 종속성을 추가합니다. 서비스에 영향을 미치지 않으면 서 변경할 수 없습니다.
  • 내부에 원치 않는 예측할 수없는로드를 추가합니다.
  • 자체 서비스의 성능은 데이터베이스 성능의 영향을받습니다 ( 클라이언트 및 데이터베이스 의 서비스 성능 만 향상하도록 서비스 를 최적화하려고합니다 ).
  • 데이터 저장소의 리소스를 정확하고 독특하게 나타내지 않을 수있는 스키마에 구현을 연결하고 있습니다. 내부 상태를 추적하거나 특정 구현 (관심해서는 안되는)을 만족시키는 데 필요한 추가 세부 정보가있을 수 있습니다.
  • 무심코 그들의 서비스 상태를 파괴하거나 손상시킬 수 있습니다 (그리고 그들은 당신이 이것을하고 있음을 알지 못할 것입니다)
  • 이러한 상황이 발생했다는 사실을 모르고 데이터베이스에서 리소스를 업데이트 / 삭제 / 제거 할 수 있습니다.

읽기 액세스 권한 만 부여 된 경우 마지막 두 지점이 발생하지 않을 수 있지만 다른 지점은 충분한 이유 이상입니다. 공유 데이터베이스는 나쁜 것입니다.

경험이 부족한 개발자 (또는 배우지 않은 사람들)는 데이터베이스를 서비스보다 더 중요하게 생각하고 데이터베이스를 실제 방식으로, 서비스를 얻는 방법으로 보는 것이 일반적입니다. 그것은 잘못된 길입니다.


4
전체 프로젝트에서 작업하는 유일한 개발자 인 경우에도 위의 모든 사항이 유효합니다. 복잡한 프로젝트를 혼자서도 관리하면 이러한 모든 문제가 발생합니다.
itsbruce

15

마이크로 서비스 아키텍처는 설명하기 어렵지만이를 고려하는 가장 좋은 방법은 컴포넌트 지향 아키텍처와 서비스 지향 아키텍처의 결합입니다. 제품군으로서의 소프트웨어는 매우 특정한 비즈니스 도메인 책임을 가진 많은 소규모 비즈니스 구성 요소로 구성됩니다. 제공된 서비스 또는 필수 서비스에서 외부 세계와의 인터페이스는 명확하게 정의 된 서비스의 API를 통해 이루어집니다.

컴포넌트 비즈니스 도메인 외부에있는 데이터베이스에 쓰거나 읽는 것조차이 스타일의 아키텍처에 위배됩니다.

그 이유는 다른 소프트웨어 구성 요소가 서비스를 통해 제공 한 API가 새로운 버전의 서비스 제공 구성 요소가 출시되면 API가 이전 버전과 호환 될 가능성이 높다는 합리적인 기대를 가지고 있기 때문입니다. "제공"구성 요소의 개발자 인 경우 API와의 하위 호환성에 대해서만 걱정하면됩니다. 데이터베이스에 대해 직접 사용자 지정 쿼리를 작성한 세 개의 다른 개발 팀이 있다는 것을 알면 내 작업이 훨씬 더 복잡해졌습니다.

더 나쁜 것은 아마도 이러한 프로젝트를 작성한 다른 팀이 중요한 프로젝트에서 스프린트 중반이며 현재 구성 요소 에서이 변경 사항을 받아 들일 수 없다는 것입니다. 이제 여러분이 소유 한 비즈니스 도메인의 구성 요소에 대한 소프트웨어 개발은 ​​다른 비즈니스 도메인의 개발에 의해 주도되고 있습니다.

서비스를 통한 완전한 상호 작용은 다양한 소프트웨어 구성 요소 간의 연결을 줄이므로 이와 같은 상황은 자주 발생하지 않습니다. 데이터베이스에서 View를 사용하는 다른 구성 요소와 관련하여 다른 사람이 쿼리를 작성하지 않으면 View와 호환됩니다. 그러나 나는 이것이 예외 사례라고 생각하며 응용 프로그램이 엄청난 양의 데이터를 읽어야하는보고 또는 배치 처리에 대해서만 수행해야한다고 생각합니다.

분명히 이것은 개발 팀이 Amazon과 같은 비즈니스 도메인으로 분리되어있는 대규모 분산 팀에서 잘 작동합니다. 소규모 개발 업체 인 경우이 모델을 사용하면 특히 큰 프로젝트를 빠르게 진행해야하지만 공급 업체 소프트웨어를 처리해야하는 경우에도이 모델의 혜택을 누릴 수 있습니다.


4

지난 20 년 동안 나는 몇 가지 큰 모듈 형 데이터베이스 디자인을 보았고 애플리케이션이 자신의 스키마 / 테이블 세트에 대한 쓰기 액세스 권한과 다른 스키마 /에 대한 읽기 액세스 권한을 갖는 David가 제안한 시나리오를 몇 번 보았습니다. 테이블 세트. 대부분 응용 프로그램 / 모듈이 읽기 전용 액세스 권한을 얻는이 데이터를 "마스터 데이터" 로 설명 할 수 있습니다 .

그 당시에는 이전 답변에서 제안한 문제를 보지 못했기 때문에 이전 답변에서 제기 된 사항을 자세히 살펴볼 가치가 있다고 생각합니다.

시나리오 : 몇 가지 구성 요소를 RDBMS에 직접 연결하면 특정 구성 요소가 성능 병목 현상이되는 것을 볼 수 있습니다.

이 의견은 마이크로 서비스가 읽을 수 있도록 로컬로 데이터 사본을 가지고 있다는 주장을 제외하고는이 의견에 동의합니다. 즉, 대부분의 성숙 된 데이터베이스는 복제를 지원 하므로 개발자의 노력없이 "마스터 데이터"를 필요에 따라 마이크로 서비스 데이터베이스에 물리적으로 복제 할 수 있습니다.

어떤 사람들은 이것을 오래된 형태로 핵심 테이블을 "부서 데이터베이스"로 복제하는 "엔터프라이즈 데이터베이스"로 인식 할 수 있습니다. 여기서 중요한 점은 일반적으로 데이터베이스가 변경된 데이터 복제 기능 (델타 전용, 이진 형식 및 소스 데이터베이스에 대한 최소 비용)을 사용하여이를 수행하는 것이 좋다는 것입니다.

반대로, 데이터베이스 선택에서이 '즉시 사용 가능한'복제 지원을 허용하지 않으면 "마스터 데이터"를 마이크로 서비스 데이터베이스로 푸시하려는 상황에 도달 할 수 있으며 이는 상당한 개발자 노력과 결과를 초래할 수 있습니다. 또한 실질적으로 덜 효율적인 메커니즘입니다.

데이터베이스를 비정규 화하고 싶을 수도 있지만 다른 모든 구성 요소에 영향을 줄 수는 없으므로

나 에게이 진술은 정확하지 않습니다. 비정규 화는 "가산 적 변화"가 아니라 "추가"변경이며 비정규 화로 인해 응용 프로그램이 중단되지 않아야합니다.

응용 프로그램을 중단시키는 유일한 방법은 응용 프로그램 코드가 "select * ..."와 같은 것을 사용하고 추가 열을 처리하지 않는 것입니다. 나에게 그것은 응용 프로그램의 버그 일 것입니까?

비정규 화는 어떻게 응용 프로그램을 중단시킬 수 있습니까? 나에게 FUD처럼 들린다.

스키마 의존성 :

예, 응용 프로그램은 이제 데이터베이스 스키마에 종속되어 있으며 이는 중요한 문제 여야한다는 의미입니다. 추가 종속성을 추가하는 것이 이상적이지는 않지만 데이터베이스 스키마에 대한 종속성이 문제가되지 않은 이유는 무엇입니까? 내가 방금 운이 좋았 니?

마스터 데이터

일반적으로 마이크로 서비스가 읽기 전용 액세스 권한을 갖기를 원하는 스키마는 가장 일반적으로 엔터프라이즈의 " 마스터 데이터 " 라고 설명 합니다. 기업에 필수적인 핵심 데이터가 있습니다.

역사적으로 이것은 우리가 의존성을 추가하는 스키마가 성숙하고 안정적이라는 것을 의미합니다.

표준화

3 명의 데이터베이스 디자이너가 표준화 된 DB 스키마를 설계하면 동일한 설계로 끝납니다. 좋아, 약간의 4NF / 5NF 변형이있을 수 있지만 별로는 아닙니다. 또한 디자이너가 모델의 유효성을 검사하도록 요청할 수있는 일련의 질문이 있으므로 디자이너는 4NF에 도달했다고 확신 할 수 있습니다 (너무 낙관적입니까? 사람들이 4NF에 어려움을 겪고 있습니까?).

업데이트 : 에 의해 4NF 여기에 내가 스키마의 모든 테이블 (모든 테이블은 4NF까지 적절하게 정상화되었다) 4NF까지 가장 높은 정규형에 도착 의미한다.

표준화 설계 프로세스는 데이터베이스 설계자가 일반적으로 표준화 된 데이터베이스 스키마에 의존한다는 생각에 익숙한 이유라고 생각합니다.

정규화 프로세스는 DB 설계를 알려진 "올바른"설계로 가져 오며 이로 인한 변형은 성능에 대한 비정규 화가되어야합니다.

  1. 지원되는 DB 유형 (JSON, ARRAY, Geo 유형 지원 등)에 따라 변형이있을 수 있습니다.
  2. 일부는 4NF / 5NF를 기준으로 변형을 주장 할 수 있습니다.
  3. 우리는 물리적 변이를 배제합니다 (중요하지 않기 때문에)
  4. 읽기 전용 액세스 권한을 부여하려는 스키마이기 때문에 DW 디자인이 아닌 OLTP 디자인으로 제한합니다.

3 명의 프로그래머가 (코드로) 구현할 설계가 주어진 경우 3 개의 다른 구현 (잠재적으로 매우 다른)에 대한 기대가됩니다.

저에게는 잠재적으로 "정규화에 대한 믿음"에 대한 의문이 있습니다.

스키마 변경을 중단 하시겠습니까?

비정규 화, 열 추가, 더 큰 스토리지를위한 열 변경, 새로운 테이블로 디자인 확장 등은 모두 끊임없는 변화이며 4 번째 정규 형식을 가진 DB 디자이너는이를 확신 할 것입니다.

열 / 테이블을 삭제하거나 주요 유형을 변경하면 주요 변경 사항이 가능합니다. 가능하지만 실제로는 여기서 전혀 문제가 발생하지 않았습니다. 아마도 주요 변경 사항이 무엇인지 이해하고 잘 관리 되었습니까?

공유 읽기 전용 스키마와 관련하여 스키마 변경이 중단되는 사례를 듣고 싶습니다.

마이크로 서비스에서 더 중요하고 중요한 것은 API 또는 데이터베이스 스키마입니까? API는 다른 세계와의 계약이기 때문입니다.

이 진술에 동의하는 동안 "데이터 수명은 영원히 있습니다"라는 엔터프라이즈 아키텍트로부터들을 수있는 중요한 경고가 있다고 생각 합니다. 즉, API가 가장 중요한 것이지만 데이터는 기업 전체에서 다소 중요하기 때문에 매우 중요합니다.

예를 들어, Data Warehouse for Business 인텔리전스 를 채워야하는 요구 사항이 있으면 API와 상관없이 비즈니스보고 관점에서 스키마 및 CDC 지원이 중요해집니다.

API 문제?

이제 API가 완벽하고 쉬운 경우 로컬 읽기 전용 액세스 권한이 아닌 항상 API를 선택하므로 모든 요점이 불분명합니다. 따라서 로컬 읽기 전용 액세스를 고려하려는 동기는 로컬 액세스로 피할 수있는 API를 사용하는 데 문제가있을 수 있다는 것입니다.

What motivates people to desire local read-only access?

API 최적화 :

LinkedIn 은 API 최적화 문제와 규모에있어 왜 중요한지에 대한 흥미로운 프레젠테이션 (2009 년부터)을 가지고 있습니다 . http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment

요컨대, API가 여러 가지 유스 케이스를 지원해야하는 경우 하나의 유스 케이스를 최적으로 지원하고 나머지는 네트워크 관점과 데이터베이스 관점에서 다소 열악한 상황으로 쉽게 들어갈 수 있습니다.

API에 LinkedIn과 동일한 세련미가없는 경우 다음과 같은 시나리오를 쉽게 얻을 수 있습니다.

  • API가 필요한 것보다 훨씬 많은 데이터를 가져옵니다 (폐기)
  • API를 여러 번 호출해야하는 Chatty API

예, 물론 캐싱을 API에 추가 할 수 있지만 궁극적으로 API 호출은 원격 호출이며 데이터가 로컬 일 때 개발자가 사용할 수있는 일련의 최적화가 있습니다.

나는 거기에 그것을 추가 할 수있는 일련의 사람들이 있다고 생각합니다.

  • 마스터 데이터를 마이크로 서비스 데이터베이스에 저렴한 비용으로 복제 (개발 비용이없고 기술적으로 효율적 임)
  • 정규화에 대한 믿음과 스키마 변경에 대한 응용 프로그램의 복원력
  • 모든 사용 사례를 쉽게 최적화하고 혼잡 / 폐기 / 비효율적 인 원격 API 호출을 피할 수있는 기능
  • 제약 및 일관성있는 디자인 측면에서 다른 이점들

이 답변은 너무 길었습니다. 사과!!


열을 추가하면 일반적으로 응용 프로그램이 중단됩니다. "급여"가있는 경우 새 열 "salary_currency"가 도입되면 모든 급여를 합산하는 응용 프로그램이 중단됩니다.
kubanczyk

정말? 내가 생각하는 "중단"의 정의에 따라 다릅니다. 앱이 "salary_currency"없이 예상대로 제작 및 작동중인 경우 해당 애플리케이션이 이제 고장난 것으로 간주하는 이유는 무엇입니까?
Rob Bygrave

응용 프로그램이 오류없이 실행되고 일부 숫자가 표시됩니다. 그러나 쓸모가 없습니다. CEO가 지난 달 월급이 5 천대가 아닌 6 백만명 (한국 원으로 지불 한 한 명의 신입 사원으로 인해)이 600 만 명이라는 것을 알면 유용하고 쓸모없는 생산량의 정의에 대해서는 많이 논의되지 않을 것이다.
kubanczyk

0

상태 관리 (잠재적으로 데이터베이스)는 Microservice 컨테이너에 배포되고 API를 통해 노출 될 수 있습니다. Microservice의 데이터베이스는 컨테이너 외부의 다른 시스템에는 표시되지 않으며 API 만 표시됩니다. 또는 API를 통해 다른 서비스 (예 : 캐시) 관리 상태를 가질 수 있습니다. 단일 배포 가능 컨테이너 내에 Microservice의 모든 종속성 (다른 서비스에 대한 API 호출 제외)을 갖는 것은 아키텍처의 주요 차이점입니다. 그것을 얻지 못하면 아키텍처를 연구하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.