흑구의 공부내용 공유

[번역글] MSA 공유 데이터베이스 패턴 (Shared database)

코딩하는흑구 2022. 9. 6. 11:49

해당 포스팅은 해당 게시글을 번역한 포스팅임을 명시합니다.

 


서론

마이크로서비스 아키텍쳐 패턴을 활용하여 온라인 스토어 애플리케이션을 개발한다고 가정해 봅시다. 대부분의 마이크로서비스에서는 일종의 데이터베이스에 데이터를 저장합니다. 예를 들어 Order Service 주문(Order) 대한 정보를 저장하고 Customer Service 고객(Customer) 대한 정보를 저장합니다.

 


 

Problem

마이크로서비스 애플리케이션의 데이터베이스 아키텍처는 무엇인가??

 


Forces

  • 서비스는 독립적으로 개발, 배포 및 확장될 수 있도록 느슨한 결합이 필요합니다.
  • 일부 비즈니스 트랜잭션은 여러 서비스에 걸쳐 처리되도록 불변성을 적용해야 합니다. 예를 들어, Place Order 유스케이스에서는 새로운 주문이 발생할 때, 고객의 신용 한도를 초과하지 않는지 확인해야 합니다. 다른 비즈니스 트랜잭션은 여러 서비스가 소유한 데이터를 업데이트 해야 합니다.
  • 일부 비즈니스 트랜잭션은 여러 서비스가 소유한 데이터를 쿼리해야 합니다. 예를 들어, 사용 가능한 크레딧을 확인하기 위한 예제에서는 고객을 쿼리하여 크레딧 한도를 찾고 주문을 확인하여 미결제 주문의 총액을 확인하여 계산하는 과정이 필요합니다.
  • 일부 쿼리는 여러 서비스가 소유한 데이터를 조인해야 합니다. 예를 들어, 특정 지역의 고객과 최근 주문을 찾기 위해서는 고객과 주문을 조인해야 합니다.
  • 확장을 위해 데이터베이스를 복제하고 샤딩해야하는 경우가 있습니다.
  • 서비스마다 데이터 저장 요구사항이 다를 있습니다. 어떤 서비스는 관계형 데이터베이스가 최선의 선택일 있고, 다른 서비스에는 복잡하고 구조화되지 않은 데이터를 저장하는데 능숙한 MongoDB 혹은 그래프 데이터를 효율적으로 저장하고 쿼리하도록 설계된 Neo4J같은 NoSQL 데이터베이스가 필요할 있습니다.

Solutions

여러 서비스에서 공유하는 (단일) 데이터베이스를 사용합니다. 서비스는 로컬 ACID 트랜잭션을 사용하여 다른 서비스가 소유한 데이터에 자유롭게 엑세스 합니다.

 


Example

OrderService와 CustomerService는 서로의 테이블에 자유롭게 엑세스합니다. 예를 들어, OrderService는 다음 ACID 트랜잭션을 사용하여 새로운 주문이 고객의 신용한도를 넘지 않도록 제한할 수 있습니다.

BEGIN TRANSACTION

SELECT 
    ORDER_TOTAL
FROM ORDERS 
WHERE CUSTOMER_ID = ?

SELECT 
    CREDIT_LIMIT
FROM CUSTOMERS 
WHERE CUSTOMER_ID = ?

INSERT INTO ORDERS …

COMMIT TRANSACTION

데이터베이스는 동시 트랜잭션이 동일한 고객에 대한 주문을 생성하려고 때에도 신용한도를 초과하지 않도록 보장합니다.

 


Resulting context

이 패턴의 이점은 다음과 같습니다.

  • 개발자는 친숙하고 간단한 ACID 트랜잭션을 활용하여 데이터 일관성을 적용할 수 있습니다.
  • 단일 데이터베이스는 운영하기 더 간단합니다.

이 패턴의 단점은 다음과 같습니다.

  • 개발시간 커플링 : 예를 들어, OrderService에서 작업하는 개발자는 동일한 테이블에 엑세스하는 다른 서비스의 개발자와 스키마에 대한 신경을 함께 써야합니다. 이러한 커플링과 추가 조정은 개발생산성을 낮출 수 있습니다.
  • 런타임 커플링 : 모든 서비스가 동일한 데이터베이스에 엑세스하기 때문에 잠재적으로 서로 간섭할 수 있습니다. 예를 들어, 러닝타임이 긴 CustomerService의 트랜잭션이 Order 테이블에 대한 lock을 보유하고 있으면 OrderService의 트랜잭션의 Order 테이블에 대한 접근이 차단됩니다.
  • 단일 데이터베이스는 모든 서비스의 데이터 저장 엑세스 요구사항을 충족하지 않을 있습니다.