MSA 아키텍처가 어려운 이유중 하나는.. 여러 마이크로 서비스간의 트랜잭션 처리이다.
기존 Monolithic 아키텍처에서는 DBMS가 제공해주는 트랜잭션 기능을 사용했다..
자세하게..
관계형 데이터베이스 + Monolithic 아키텍처를 도입한 서버 Application은
DB 서버에서 제공하는 트랜잭션의 Commit 과 Rollback을 이용하여 데이터를 일관성 있게 제어가 가능하다.
하지만..
MSA 구조에서는 Application 과 DB 가 분산 되어..
트랜잭션 처리를 DBMS에서 제공하는 기능을 통해 달성할 수 없다.
MSA 구조에서는 각 서비스별로 DB 인스턴스 + Application이 분리 됨에 따라
관계형으로 맺어진 Entity들은 서로가 다른 인스턴스로 운영되고,
그들 리소스를 받기 때문에 데이터의 일관성이 무너지게 되었다.
그러면 ..
MSA 구조에서는 어떻게 여러 서비스에 걸친 트랜잭션을 처리할까..
두가지 방법이 있다.
1. Two Phase Commit
2. Saga Pattern
먼저, Two Phase Commit 을 수행할 시스템 구조를 보자.
Monolithic 구조에서 Two Phase Commit
하나의 Application이 Coordinator(조정자, 분산 DB 트랜잭션 관리자) 를 바라보고 있고
Coordinator가 여러 개의 DataBase를 바라보는 상황이다.
MSA 구조에서 Two Phase Commit
MSA에서는, 위 그림과 같은 구조로 볼 수 있다.
모놀리틱을 가진 형태는 하나의 Application에서 여러개의 DB의 인스턴스를 직접 가지고 있으나..
MSA에서는(Order 입장에서..) 인스턴스(UserDB, DeliverDB)를 직접 가지고 있지 않기 때문에
트랜잭션이 가능한 상태인지 확인이 되어야 한다.
Coordinator는 Order 서버가 된다.
본격적으로 알아보자.
Two Phase Commit (2PC)
분산 DB 환경에서 사용되는 방법이다.
2단계에 거쳐서 데이터를 영속화 하는 방식이다.
분산 트랜잭션(Distributed Transaction)에 참여하는 모든 노드들에 대하여
'Everything Commit or Everything Rollback'을 보장하는 방법!
Two Phase Commit 방식은 아래 그림과 같이..
연결된 DB가 여러개로 분산되었을 때.. 사용하며
트랜잭션을 조율하는 조정자(Coordinator)가 존재한다.
Two Phase Commit 절차
1. Prepare단계
Coordinator는 분산된 각 DB에 Commit 할 준비가 되었는지 물어본다. (Prepare 메세지)
<참고>
2PC Lock (DB에 따라 방식이 다른듯 하다..)
Prepare 단계 이전에.. DB에 데이터를 write 를 하면 트랜잭션에 의한 Lock이 설정된다.
or
분산 트랜잭션에 관여된 노드는 Commit 시점에 Commit이 가능한 경우 자원에
Distributed Lock을 걸게 된다.
DB는 Prepare를 마친 상태에서 네트워크의 이상으로..
Coordinator로 부터 다음 메세지(Commit or Rollback)를 못받을 수도 있다..
그러면..
DB는 해당 트랜잭션을 커밋해야 할지 롤백해야 할지 판단 할 수 없다.
이때 prepare 된 리소스에 Lock 처리를 한 상태로 Blocking 되는데.. 이러한 경우를
트랜잭션이 In-doubt 상태 에 있다고 표현한다.
2. Commit or Rollback 단계
Coordinator는 첫 번째 단계에서 전달한 메세지의 응답을 기다리고,
모든 응답의 이상이 없다면 Commit 메세지를 요청한다.
각 DB는 Commit을 수행한다.
모든 DB에서 트랜잭션 처리가 완료되면 전체 트랜잭션을 종료하고
모든 DB는 데이터를 영속화 한다.
(추측, 각 DB는 Ready 메세지를 응답하는 순간 부터 Commit을 수행할 때 까지 트랜잭션)
만약, 두 단계를 거치는 과정에서 연관된 단 하나의 DB라도 Ready를 못할 상황이면
모든 DB에게 Rollback을 요청한다.
Two Phase Commit 방식의 문제점
1. Coordinator 가 처리하기 때문에.. 연관된 모든 DB가 동일한 제품군이어야 한다.
2. 여러 DB에 대해 Blocking 되기 때문에 불필요한 Blocking 되는 시간이 생길 수 있다.
추가로, 하나의 DB가 문제가 생겨 응답을 주지 못하거나 Coordinator가 응답을 못받은 경우..
전체가 Blocking 된다.
3. 하나의 API end point 를 통해 서비스 요청이 들어오고 하나의 Application 내에
DB가 분산되어 있을 때 사용하는 형태로 되어있다. 따라서 MSA에서는
각기 다른 App에서 API간 통신을 통해 요청이 이루어 지므로.. 쉽지 않다.
4. Coordinator에 오류가 발생하면 Coordinator가 복구 될 때 까지 모든 트랜잭션이 지연된다.
5. DBMS간 분산 트랜잭션을 지원해야 적용가능하다.
6. NoSQL에서는 지원하지 않는다.
Two Phase Commit (feat. MSA)
MSA 아키텍처가 어려운 이유중 하나는.. 여러 마이크로 서비스간의 트랜잭션 처리이다.
기존 Monolithic 아키텍처에서는 DBMS가 제공해주는 트랜잭션 기능을 사용했다..
자세하게..
관계형 데이터베이스 + Monolithic 아키텍처를 도입한 서버 Application은
DB 서버에서 제공하는 트랜잭션의 Commit 과 Rollback을 이용하여 데이터를 일관성 있게 제어가 가능하다.
하지만..
MSA 구조에서는 Application 과 DB 가 분산 되어..
트랜잭션 처리를 DBMS에서 제공하는 기능을 통해 달성할 수 없다.
자세하게..
MSA 구조에서는 각 서비스별로 DB 인스턴스 + Application이 분리 됨에 따라
관계형으로 맺어진 Entity들은 서로가 다른 인스턴스로 운영되고,
그들 리소스를 받기 때문에 데이터의 일관성이 무너지게 되었다.
그러면 ..
MSA 구조에서는 어떻게 여러 서비스에 걸친 트랜잭션을 처리할까..
두가지 방법이 있다.
1. Two Phase Commit
2. Saga Pattern
먼저, Two Phase Commit 을 수행할 시스템 구조를 보자.
Monolithic 구조에서 Two Phase Commit
하나의 Application이 Coordinator(조정자, 분산 DB 트랜잭션 관리자) 를 바라보고 있고
Coordinator가 여러 개의 DataBase를 바라보는 상황이다.
MSA 구조에서 Two Phase Commit
MSA에서는, 위 그림과 같은 구조로 볼 수 있다.
모놀리틱을 가진 형태는 하나의 Application에서 여러개의 DB의 인스턴스를 직접 가지고 있으나..
MSA에서는(Order 입장에서..) 인스턴스(UserDB, DeliverDB)를 직접 가지고 있지 않기 때문에
트랜잭션이 가능한 상태인지 확인이 되어야 한다.
Coordinator는 Order 서버가 된다.
본격적으로 알아보자.
Two Phase Commit (2PC)
분산 DB 환경에서 사용되는 방법이다.
2단계에 거쳐서 데이터를 영속화 하는 방식이다.
분산 트랜잭션(Distributed Transaction)에 참여하는 모든 노드들에 대하여
'Everything Commit or Everything Rollback'을 보장하는 방법!
Two Phase Commit 방식은 아래 그림과 같이..
연결된 DB가 여러개로 분산되었을 때.. 사용하며
트랜잭션을 조율하는 조정자(Coordinator)가 존재한다.
Two Phase Commit 절차
1. Prepare단계
Coordinator는 분산된 각 DB에 Commit 할 준비가 되었는지 물어본다. (Prepare 메세지)
<참고>
2PC Lock (DB에 따라 방식이 다른듯 하다..)
Prepare 단계 이전에.. DB에 데이터를 write 를 하면 트랜잭션에 의한 Lock이 설정된다.
or
분산 트랜잭션에 관여된 노드는 Commit 시점에 Commit이 가능한 경우 자원에
Distributed Lock을 걸게 된다.
<참고>
DB는 Prepare를 마친 상태에서 네트워크의 이상으로..
Coordinator로 부터 다음 메세지(Commit or Rollback)를 못받을 수도 있다..
그러면..
DB는 해당 트랜잭션을 커밋해야 할지 롤백해야 할지 판단 할 수 없다.
이때 prepare 된 리소스에 Lock 처리를 한 상태로 Blocking 되는데.. 이러한 경우를
트랜잭션이 In-doubt 상태 에 있다고 표현한다.
2. Commit or Rollback 단계
Coordinator는 첫 번째 단계에서 전달한 메세지의 응답을 기다리고,
모든 응답의 이상이 없다면 Commit 메세지를 요청한다.
각 DB는 Commit을 수행한다.
모든 DB에서 트랜잭션 처리가 완료되면 전체 트랜잭션을 종료하고
모든 DB는 데이터를 영속화 한다.
(추측, 각 DB는 Ready 메세지를 응답하는 순간 부터 Commit을 수행할 때 까지 트랜잭션)
만약, 두 단계를 거치는 과정에서 연관된 단 하나의 DB라도 Ready를 못할 상황이면
모든 DB에게 Rollback을 요청한다.
Two Phase Commit 방식의 문제점
1. Coordinator 가 처리하기 때문에.. 연관된 모든 DB가 동일한 제품군이어야 한다.
2. 여러 DB에 대해 Blocking 되기 때문에 불필요한 Blocking 되는 시간이 생길 수 있다.
추가로, 하나의 DB가 문제가 생겨 응답을 주지 못하거나 Coordinator가 응답을 못받은 경우..
전체가 Blocking 된다.
3. 하나의 API end point 를 통해 서비스 요청이 들어오고 하나의 Application 내에
DB가 분산되어 있을 때 사용하는 형태로 되어있다. 따라서 MSA에서는
각기 다른 App에서 API간 통신을 통해 요청이 이루어 지므로.. 쉽지 않다.
4. Coordinator에 오류가 발생하면 Coordinator가 복구 될 때 까지 모든 트랜잭션이 지연된다.
5. DBMS간 분산 트랜잭션을 지원해야 적용가능하다.
6. NoSQL에서는 지원하지 않는다.
'대규모 시스템 설계' 카테고리의 다른 글