모놀리스에서 마이크로 서비스로 마이그레이션 할 때 외래 키 제약 조건을 처리하는 방법은 무엇입니까?


18

우리 팀은 단일 ASP.NET 응용 프로그램에서 .NET Core 및 Kubernetes로 마이그레이션하고 있습니다. 코드 변경이 예상대로 진행되는 것처럼 보이지만 팀에서 데이터베이스와 관련하여 많은 불일치가 발생합니다.

우리는 현재 전체 비즈니스에 대한 모든 데이터를 저장하는 다소 큰 SQL Server 데이터베이스를 보유하고 있습니다. 우리는 코드를 하나의 (논리적) 데이터베이스의 카탈로그 데이터, 다른 데이터베이스의 인벤토리 데이터, 다른 주문의 순서 등으로 나누는 것과 비슷한 방식으로 데이터베이스를 분할하고 각 마이크로 서비스는 데이터베이스의 게이트 키퍼가 될 것을 제안합니다 .

여기서는 마이크로 서비스 경계를 ​​넘는 외래 키를 제거해야하고 경계를 넘어 도달하는 장면 및 뷰는 금지되어야합니다. 모든 데이터 모델은 동일한 실제 데이터베이스에있을 수도 있고 상주하지 않을 수도 있지만, 그렇게해도 직접 서로 상호 작용해서는 안됩니다. 주문은 여전히 ​​ID별로 카탈로그 항목을 참조 할 수 있지만 데이터 무결성은 데이터베이스 레벨에서 엄격하게 적용되지 않으며 해당 데이터는 SQL이 아닌 코드로 결합되어야합니다.

마이크로 서비스로의 전환과 함께 제공되는 확장 성 이점을 얻는 데있어 이러한 절충이 필요한 절충점이라고 생각합니다. 우리가 솔기를 현명하게 선택하고 그 주위에서 발전하는 한 괜찮습니다. 다른 팀원들은 모든 것이 동일한 모 놀리 식 데이터베이스에 있어야하므로 모든 것이 ACID가 될 수 있고 모든 곳에서 참조 무결성을 유지해야합니다.

이것은 나의 질문에 나를 데리고 온다. 첫째, 외래 키 제약에 대한 나의 입장과 그럴듯한 입장입니까? 그렇다면 누구든지 동료에게 제공 할 수있는 신뢰할만한 독서 자료를 알고 있습니까? 그들의 입장은 거의 종교적이며 마틴 파울러 자신이 부족하다고 말한 것에 의해 흔들리는 것처럼 보이지 않습니다.


5
참조 무결성은 매우 중요합니다. 데이터베이스의 규모가 실제로 병목 현상입니까? 마이크로 서비스 스타일 확장 성이 정말로 필요합니까? 아키텍처의 변화가 조직에 적합한 지 나보다 더 잘 알고 있지만 많은 사용 사례에 적합하지 않다는 것을 고려하십시오. 보다 매력적인 트레이드 오프로 확장 할 수있는 다른 방법이있을 수 있습니다. 예를 들어 초당 데이터베이스 쿼리가 너무 높으면 데이터베이스 복제 만 있으면됩니다. 또한 마이크로 서비스를 사용하지 않고도 웹 서버를 수평으로 확장 할 수 있습니다.
amon September

좋은 지적입니다. 우리는 단기적인 이익을 위해 이러한 옵션 중 일부를 조사하고 있습니다. 그러나 마이크로 서비스로의 전환은 긴 게임입니다. 제 생각에는 몇 개월이 아닌 몇 년 동안 확장 할 수 있습니다.
Raymond Saltrelli

3
재고가 한 개 밖에 없을 때 다른 사람이 같은 제품을 주문했기 때문에 고객이 0.05ms 더 빠른 주문을 취소한다는 사실에 고객이 크게 기뻐할 것입니다.
앤디

@amon이 질문에 대한 답을 구하십시오. 이것은 좋은 질문이며 장단점을 공정하게 표현해야합니다.
mcottle

@mcottle 알았어!
amon

답변:


19

이는 시스템의 규모와 실제 문제의 크기에 따라 사용자의 상황에 따라 달라지기 때문에 명확한 해결책은 없습니다. 데이터베이스가 실제로 병목 현상입니까?

이 (안타깝게도 다소 긴) 답변은“마이크로 서비스는 나쁘고 인생에는 모 놀리 식입니다!”와 같은 내용을 읽게되지만 이것이 저의 의도는 아닙니다. 내 요점은 마이크로 서비스와 분산 데이터베이스가 다양한 문제를 해결할 수는 있지만 자체 문제가 없어야한다는 것입니다. 아키텍처를 강력하게 주장하려면 이러한 문제가 적용되지 않고 완화 될 수 있으며이 아키텍처가 비즈니스 요구에 가장 적합한 선택임을 보여 주어야합니다.

분산 데이터는 어렵다.

더 나은 스케일링을 가능하게하는 동일한 유연성은 더 약한 보증의 단점입니다. 특히 분산 시스템은 추론하기 가 훨씬 어렵습니다.

원자 업데이트, 트랜잭션, 일관성 / 참조 무결성 및 내구성은 매우 중요하며 급히 포기해서는 안됩니다. 데이터가 불완전하거나 오래되었거나 완전히 틀린 경우에는 데이터가 거의 없습니다. 비즈니스 요구 사항으로 ACID를 가지고 있지만 즉시 사용할 수없는 데이터베이스 기술을 사용하는 경우 (예 : 많은 NoSQL 데이터베이스 또는 마이크로 서비스 당 DB 아키텍처), 응용 프로그램 은 그 차이를 메워 그 보증을 제공해야합니다.

  • 이것은 불가능하지는 않지만 제대로하기에는 까다 롭습니다. 매우 까다 롭습니다. 특히 각 데이터베이스에 여러 작성자가있는 분산 설정에서. 이러한 어려움은 데이터 손실, 불일치 데이터 등을 포함하여 버그가 발생할 가능성이 높습니다.

    예를 들어, Cassandra 분석 부터 시작하여 잘 알려진 분산 데이터베이스 시스템Jepsen 분석을 읽어보십시오 . 나는 그 분석의 절반을 이해하지 못하지만 TL; DR은 분산 시스템이 너무 어려워서 업계를 선도하는 프로젝트조차도 뒤늦게 분명하게 보일 수있는 방식으로 잘못 이해하기도합니다.

  • 분산 시스템은 또한 더 큰 개발 노력을 암시합니다. 어느 정도까지는 개발 비용이나 하드웨어 강화 비용 사이에 직접적인 상충 관계가 있습니다.

예 : 매달린 참조

실제로 ACID를 완화 할 수 있는지 여부와 방법을 확인하려면 컴퓨터 과학이 아니라 비즈니스 요구 사항을 살펴 봐야합니다. 예를 들어 많은 외래 관계는 그다지 중요하지 않을 수 있습니다. 제품 – 범주 n : m 관계를 고려하십시오. RDBMS에서는 기존 제품과 기존 범주 만 해당 관계의 일부가 될 수 있도록 외래 키 제약 조건을 사용할 수 있습니다. 별도의 제품 및 카테고리 서비스를 도입하고 제품 또는 카테고리를 삭제하면 어떻게됩니까?

이 경우 큰 문제가되지 않을 수 있으며 더 이상 존재하지 않는 제품이나 범주를 필터링하도록 응용 프로그램을 작성할 수 있습니다. 그러나 트레이드 오프가 있습니다!

  • 여기에는 JOIN여러 데이터베이스 / 마이크로 서비스에 대한 응용 프로그램 수준이 필요할 수 있으며 데이터베이스 서버에서 응용 프로그램으로 처리가 이동하기 만합니다. 총로드가 증가하고 네트워크를 통해 추가 데이터를 이동해야합니다.

  • 페이지 매김으로 혼란 스러울 수 있습니다. 예를 들어 카테고리에서 다음 25 개의 제품을 요청하고 해당 응답에서 사용할 수없는 제품을 걸러냅니다. 이제 응용 프로그램에 23 개의 제품이 표시됩니다. 이론적으로 제품이없는 페이지도 가능합니다!

  • 각 관련 변경 후 또는 정기적으로 매달린 참조를 정리하는 스크립트를 실행하는 것이 좋습니다. 이러한 스크립트는 여전히 존재하는지 여부를 확인하기 위해 백업 데이터베이스 / 마이크로 서비스에서 모든 제품 / 카테고리를 요청해야하기 때문에 상당히 비쌉니다.

  • 이것은 분명해야하지만 명확성을 위해 ID를 재사용하지 마십시오. 자동 증분 스타일 ID는 괜찮을 수도 있고 아닐 수도 있습니다. GUID 또는 해시는 예를 들어 항목이 데이터베이스에 삽입되기 전에 ID를 할당 할 수있는 등의 유연성을 제공합니다.

예 : 동시 주문

이제 제품 – 주문 관계를 고려하십시오. 제품이 삭제되거나 변경되면 주문은 어떻게됩니까? 이제 간단하게 디스크 공간을 거래 할 수 있도록 관련 제품 데이터를 주문 항목에 간단히 복사 할 수 있습니다. 그러나 제품 가격이 변경되거나 해당 제품을 주문하기 직전에 제품을 사용할 수 없게되면 어떻게됩니까? 분산 시스템에서는 효과가 전파되는 데 시간이 걸리며 오래된 데이터로 인해 순서가 진행될 수 있습니다.

다시이 문제에 접근하는 방법은 비즈니스 요구 사항에 따라 다릅니다. 오래된 주문이 허용 될 수 있으며 나중에 주문을 이행 할 수없는 경우 주문을 취소 할 수 있습니다.

그러나 이는 동시 설정과 같은 옵션이 아닐 수도 있습니다. 처음 10 초 이내에 콘서트 티켓을 구매하기 위해 서두르는 3000 명의 사람들을 고려하고, 가용성의 변화가 전파 되려면 10ms가 필요하다고 가정하자. 여러 사람에게 마지막 티켓을 판매 할 확률은 얼마입니까? 와 그 충돌이 처리하지만, 포아송 분포를 사용하는 방법에 따라 달라집니다 λ = 3000 / (10s / 10ms) = 3우리가 얻을 P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%10ms의 간격 당 충돌의 기회를. 사기를 저 지르지 않고 주문의 대부분을 판매하고 나중에 취소 할 수 있는지 여부는 법무 부서와 흥미로운 대화로 이어질 수 있습니다.

실용주의는 최고의 기능을 체리 피킹하는 것을 의미합니다.

다행스럽게도 분산 데이터베이스 모델로 이동할 필요가 없다는 것이 좋은 소식입니다. 마이크로 서비스를“적절하게”하지 않으면 마이크로 서비스 클럽을 탈퇴 할 수 없습니다. 그러한 클럽이없고 마이크로 서비스를 구축 할 수있는 진정한 방법이 없기 때문입니다.

실용주의는 항상 승리하므로 문제를 해결할 때 다양한 접근 방식을 혼합하고 일치시킵니다. 이는 중앙 데이터베이스가있는 마이크로 서비스를 의미 할 수도 있습니다. 실제로 분산 데이터베이스의 고통을 겪지 않아도됩니다.

마이크로 서비스없이 확장 할 수 있습니다.

마이크로 서비스에는 두 가지 주요 이점이 있습니다.

  • 개별 팀이 독립적으로 개발 및 배포 할 수있는 조직의 이점 (서비스는 안정적인 인터페이스를 제공해야 함).
  • 각 마이크로 서비스를 독립적 으로 확장 할 수있는 운영상의 이점 .

독립적 인 확장이 필요하지 않은 경우 마이크로 서비스는 그다지 매력적이지 않습니다.

데이터베이스 서버는 이미 읽기 복제본을 추가하여 독립적으로 확장 할 수있는 일종의 서비스입니다. 저장 프로 시저를 언급했습니다. 그것들을 줄이면 다른 확장 성 토론이 무의미한 영향을 미칠 수 있습니다.

또한 모든 서비스를 라이브러리로 포함하는 확장 가능한 단일체를 가질 수 있습니다. 그런 다음 더 많은 모노리스 인스턴스를 시작하여 확장 할 수 있습니다. 물론 각 인스턴스는 상태 비 저장이어야합니다.

이는 모놀리스가 너무 커서 합리적으로 배포 할 수 없을 때까지 또는 일부 서비스에 특별한 리소스 요구 사항이있어 독립적으로 확장하려는 경우가 있습니다. 추가 자원과 관련된 문제점 도메인에는 별도의 데이터 모델이 포함되지 않을 수 있습니다.

강력한 비즈니스 사례가 있습니까?

조직의 비즈니스 요구를 알고 있으므로 분석을 기반으로 마이크로 서비스 당 데이터베이스 아키텍처에 대한 인수를 만들 수 있습니다.

  • 특정 규모가 필요하며이 아키텍처는 이러한 설정 및 대체 솔루션에 대한 개발 노력의 증가를 고려하여 확장 성을 확보하기위한 가장 비용 효율적인 접근 방법입니다. 과
  • 비즈니스 요구 사항에 따라 위에서 설명한 것과 같은 다양한 문제가 발생하지 않고 관련 ACID 보증이 완화됩니다.

반대로,이를 입증 할 수없는 경우, 특히 현재 데이터베이스 설계가 미래에 충분한 규모를 지원할 수있는 경우 (동료가 생각하는 것처럼), 귀하도 답을 얻습니다.

확장성에 큰 YAGNI 구성 요소도 있습니다. 불확실성에 직면 한 것은 현재 확장 성을 구축하기위한 전략적 비즈니스 결정입니다 (총 비용은 낮지 만 기회 비용이 필요하며 필요하지 않을 수 있음). 실제 규모에 대한 아이디어). 이것은 주로 기술적 결정이 아닙니다.


훌륭한 답변입니다. 감사합니다. 이 진술에 대해 자세히 설명해 주시겠습니까? 절차 수를 줄이면 성능에 큰 영향을 줄 수 있습니까? 저장 프로 시저를 언급했습니다. 그것들을 줄이면 다른 확장 성 토론이 무의미한 영향을 미칠 수 있습니다.
alan

1
@alan 저장 프로시 저는 유용하게 사용할 수 있지만 두 가지 성능 문제가 있습니다. (1) 데이터베이스를 더욱 복잡하게 쿼리하기가 더 어렵습니다. (2) sprocs를 사용한다는 것은 DB 서버에서 더 많은 작업을 수행하는 것을 의미합니다. OP는 더 확장하기 위해 DB를 분할하려고하지만 복잡한 절차를 피하면 이미 헤드 룸을 제공 할 수 있습니다. 물론, sprocs와 복잡한 쿼리는 쿼리 응답을 위해 DB에서 전송해야하는 데이터의 양을 최소화 할 때와 같이 성능에 좋습니다. DB를 분할하면 서버 간 JOIN이 필요할 때이 문제가 악화됩니다.
amon

0

두 가지 접근법 모두 그럴듯하다고 생각합니다. ACID 및 모 놀리 식 데이터베이스의 이점을 희생하는 확장 성을 확보하고 현재 아키텍처를 유지하고보다 분산 된 아키텍처의 확장 성과 민첩성을 희생하도록 선택할 수 있습니다. 올바른 결정은 향후 몇 년 동안 현재 비즈니스 모델과 buz 전략에서 나올 것입니다. 순수하게 기술적 인 관점에서 볼 때 모 놀리 식을 유지하고보다 분산 된 접근 방식으로 전환하는 데 어려움이 있습니다. 시스템을 분석하고 모 놀리 식 아키텍처에서 대기하거나 계속해야 할 사항을 결정하기 위해 위험, 비용 및 이점을 확장하고 평가하는 데 어떤 응용 프로그램 / 모듈 / 비즈니스 프로세스가 더 중요한지 확인합니다.


-1

당신의 입장은 그럴듯하고 정확합니다.

양모 DB 중독자에게 염색하는 방법은 또 다른 질문입니다. 두 가지 옵션이 있습니다.

  1. DB가 한계에 도달 한 구체적인 예를 찾으십시오. 예를 들어 '아카이브 테이블'이 있습니까? 왜 괜찮아? 초당 최대 주문 수는 몇 개입니까? 등. DB가 요구 사항을 충족하지 않으며 솔루션이이를 수정 함을 보여줍니다.

  2. 고가의 계약자를 고용하여 최상의 솔루션을 찾으십시오. 비용이 많이 들고 블로그를 가지고 있기 때문에 모두가 믿을 수 있습니다.


1
나는 -1은 아니지만 이것이 좋은 대답이 되려면 포인트 2의 실수를 잃어 버리고 여러 데이터베이스가 필요할 때 확장 할 것입니다. 아카이브 테이블이 파티셔닝을 지원하지 않는 데이터베이스의 반 패턴이라고 생각하지는 않습니다. 현재 사용중인 데이터베이스에는 26 개의 테이블> 10M 행을 가진 약 130GB의 데이터가 있으며 성능은 원격으로 데이터베이스를 분할해야하는 문제가 아닙니다. 그래서 저는 회의적이며 왜 이것이 좋은 아이디어인지, 그리고 그것이 언제 이루어져야하는지 듣고 싶습니다.이 답변은 제가 지금까지 본 것 중 가장 가깝습니다.
mcottle

잘. 아카이브 테이블은 FK 제약 조건을 제거하기 때문에 언급했습니다. 갑옷에 nk. 마이크로 서비스에 의한 분할은 db 크기의 크기가 아니므로 마이크로 서비스를 분리 할 수 ​​있습니다. 하나를 끄고 버릴 수 없다면 실제로 마이크로 서비스가 아닙니다. re point 2. OP는 MF에 대해 언급하고있다. 그들은 문자 그대로 그를 생각하고 고용하여 db를 나누라고 할 수있다
Ewan

"만약 당신이 그것을 끄고 버릴 수 없다면, 그것은 실제로 마이크로 서비스가 아닙니다." 이는 서비스 자체에 해당하지만 서비스에 자체 데이터베이스가 필요한 이유에 대한 인수는 아닙니다. 궁극적으로 데이터베이스 자체는 마이크로 서비스가 사용하는 서비스입니다. 마이크로 서비스는 실제로 사용하는 데이터가 별도의 데이터베이스에 있는지 또는 공유 데이터베이스에 있는지를 알거나 신경 쓰지 않습니다. 이 마이크로 서비스 사본을 스핀 업 또는 다운 할 수 있으며 실제로 변경되는 것은 없습니다.
Chris Pratt

서비스 별 데이터베이스에 대한 가장 좋은 주장은 연결 제한입니다. 연결 풀링을 사용하는 것은 드문 일이 아니므로 각 마이크로 서비스는 이미 데이터베이스 인스턴스에 대한 다중 연결을 필요로하므로 각각의 마이크로 서비스마다 각각 고유 한 풀이있는 다중 인스턴스를 가질 수 있습니다. 결과적으로 데이터베이스의 모든 연결을 처리 할 수있는 기능을 완전히 사용하지 못하게 될 수도 있습니다.
Chris Pratt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.