02 MSA 데이터 정합성
02 MSA 데이터 정합성
1. Note
- 여러가지 패턴은 인지하고 사용해야 할듯.
- 주요한 패턴은 Saga Pattern
- 하지만 여러가지 같이 사용하기도 함!
- 여기에서 특정 패턴만 고정으로 사용하지는 X
- 여러 패턴을 활용해서 필요한 것들을 작업함.
- 디자인패턴과 비슷한 느낌으로 파악!
2. 데이터 정합성 패턴 종류
| 방식 | 특징 | 장점 | 단점 |
|---|---|---|---|
| 2PC (Two-Phase Commit) | 중앙 Coordinator 기반 전역 분산 트랜잭션 | 강한 정합성 보장 | 성능 저하, Lock 유지, 확장성 낮음 |
| Saga Pattern | 로컬 트랜잭션 + 보상 트랜잭션 기반 | MSA 친화적, 확장성 높음 | 보상 로직 필요, 일시적 불일치 허용 |
| Eventual Consistency | 비동기 이벤트 기반 최종 일관성 | 높은 성능, 느슨한 결합 | 즉시 정합성 보장 어려움 |
| Outbox Pattern | DB 저장 + 이벤트 발행 정합성 보장 | 메시지 유실 방지 | 구현 복잡도 증가 |
| TCC (Try-Confirm-Cancel) | 예약 후 확정/취소 방식의 분산 트랜잭션 | Saga보다 강한 정합성 | 구현 난이도 높음 |
| CQRS + Event Sourcing | 쓰기/읽기 분리 + 이벤트 기반 상태 저장 | 감사 로그, 상태 재현 용이 | 설계 난이도 및 운영 복잡도 증가 |
3. 2PC (Two-Phase Commit)
1. 개념
- 2PC(Two-Phase Commit)는 여러 서비스(DB)에 걸친 작업을 하나의 트랜잭션처럼 처리하는 분산 트랜잭션 방식
- 중앙 Coordinator 가 각 서비스의 Commit 가능 여부를 확인한 뒤 최종 Commit 또는 Rollback 수행
- 모든 서비스가 성공해야 Commit 되며, 하나라도 실패하면 전체 Rollback 처리
- 강한 데이터 정합성을 보장하지만 성능 저하와 Lock 유지 문제가 존재
- MSA 환경에서는 서비스 간 결합도가 높아 제한적으로 사용됨
2. 성공
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Coordinator
- 분산 트랜잭션 시작
[3] Order Service (Prepare OK)
- 주문 생성 가능 상태 확인
- Commit 전 대기 상태 유지
[4] Payment Service (Prepare OK)
- 결제 가능 상태 확인
- Commit 전 대기 상태 유지
[5] Inventory Service (Prepare OK)
- 재고 차감 가능 상태 확인
- Commit 전 대기 상태 유지
[6] Coordinator
- 모든 서비스가 성공 응답(YES)
- Commit 가능 상태 판단
[7] 전체 Commit 실행
- 모든 서비스에 실제 Commit 명령 전달
- 데이터 최종 반영
[8] 최종 완료
- 주문, 결제, 재고 처리 완료
- 데이터 정합성 유지
3. 실패
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Coordinator
- 분산 트랜잭션 시작
[3] Order Service (Prepare OK)
- 주문 생성 가능 상태 확인
- Commit 전 대기 상태 유지
[4] Payment Service (Prepare OK)
- 결제 가능 상태 확인
- Commit 전 대기 상태 유지
[5] Inventory Service (Prepare FAIL)
- 재고 부족 또는 처리 실패 발생
- Commit 불가능 응답 반환
[6] Coordinator
- 하나의 서비스 실패 감지
- 전체 트랜잭션 실패 판단
[7] 전체 Rollback 실행
- Prepare 완료된 서비스들도 전부 취소
- Order Rollback
- Payment Rollback
[8] 최종 실패
- 주문 전체 실패 처리
- 데이터 정합성 유지
4. Saga Pattern
1. 개념
- Saga Pattern은 MSA 환경에서 서비스별 로컬 트랜잭션을 사용하면서 데이터 정합성을 유지하는 패턴
- 각 서비스가 자신의 트랜잭션을 처리한 뒤 다음 서비스로 작업을 전달
- 중간에 실패가 발생하면 이전 작업을 보상 트랜잭션(Compensation Transaction)으로 취소
- 2PC처럼 전역 트랜잭션을 사용하지 않아 확장성과 서비스 독립성에 유리
- MSA 환경에서 가장 많이 사용되는 데이터 정합성 패턴 중 하나
2. 성공 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 생성
- 로컬 트랜잭션 Commit
[3] Payment Service
- 결제 처리
- 로컬 트랜잭션 Commit
[4] Inventory Service
- 재고 차감
- 로컬 트랜잭션 Commit
[5] 최종 완료
- 주문, 결제, 재고 처리 완료
- 데이터 정합성 유지
3. 실패 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 생성
- 로컬 트랜잭션 Commit
[3] Payment Service
- 결제 처리
- 로컬 트랜잭션 Commit
[4] Inventory Service (FAIL)
- 재고 부족 또는 처리 실패 발생
[5] 보상 트랜잭션 시작
- 실패 감지
- 이전 작업 취소 시작
[6] Payment Service (Compensation)
- 결제 환불 처리
[7] Order Service (Compensation)
- 주문 취소 처리
[8] 최종 실패
- 전체 주문 실패 처리
- 데이터 정합성 유지
5. Eventual Consistency
1. 개념
- Eventual Consistency(최종 일관성)는 서비스 간 데이터가 즉시 일치하지 않더라도, 시간이 지나면 최종적으로 일관된 상태가 되는 방식
- 주로 이벤트(Event) 기반 비동기 처리 방식으로 데이터 정합성을 맞춤
- 일부 서비스 처리 실패 시 즉시 Rollback 하지 않고 Retry 를 통해 재처리
- 강한 정합성보다 성능과 확장성을 우선하는 방식
- MSA 환경에서 Saga Pattern, CQRS 와 함께 자주 사용됨
2. 성공 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 처리 완료
- 로컬 트랜잭션 Commit
[3] Event 발행
- OrderCompleted Event 발행
[4] Point Service
- 이벤트 수신
- 포인트 적립 처리
[5] 최종 완료
- 일정 시간 이후 데이터 동기화 완료
- 최종 데이터 정합성 유지
3. 실패 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 처리 완료
- 로컬 트랜잭션 Commit
[3] Event 발행
- OrderCompleted Event 발행
[4] Point Service (FAIL)
- 포인트 적립 실패 발생
[5] Retry 수행(☆)
- 리트라이 후에 실패시 간격을 두고 재시도함.
- 보통 일정 횟수 후에 취소되는 패턴을 가짐.
[6] 최종 완료
- 포인트 적립 성공
- 데이터 최종 정합성 유지
6. Outbox Pattern
1. 개념
- Outbox Pattern은 DB 저장과 이벤트 발행을 함께 처리하여 메시지 유실을 방지하는 패턴
- 비즈니스 데이터 저장과 이벤트 발행 사이의 정합성 문제를 해결하기 위해 사용
- 데이터 저장 시 Outbox 테이블에 이벤트 정보를 함께 저장
- 이후 별도 프로세스가 Outbox 데이터를 읽어 메시지 브로커(Kafka 등)로 이벤트 발행
- 이벤트 발행 실패 시 재시도를 통해 최종 데이터 정합성을 유지
2. 성공 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 데이터 저장
- Outbox 테이블에 Event 저장
- 하나의 트랜잭션으로 Commit
[3] Outbox Publisher
- Outbox 테이블 조회
- OrderCreated Event 발행
[4] Message Broker
- Kafka(Event) 전달
[5] Consumer Service
- 이벤트 수신 후 후속 처리 수행
[6] 최종 완료
- 이벤트 정상 발행 완료
- 데이터 정합성 유지
3. 실패 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[1] Client 요청
- 사용자가 주문 요청 전송
[2] Order Service
- 주문 데이터 저장
- Outbox 테이블에 Event 저장
- 하나의 트랜잭션으로 Commit
[3] Outbox Publisher (FAIL)
- Kafka 발행 실패 발생
[4] Event 유지
- Outbox 테이블 데이터 유지
- 메시지 유실 방지
[5] Retry 수행
- 일정 시간 이후 이벤트 재발행 시도
[6] 최종 완료
- 이벤트 발행 성공
- Consumer Service 정상 처리
- 데이터 정합성 유지
7. TCC (Try-Confirm-Cancel)
1. 개념
- TCC(Try-Confirm-Cancel)는 분산 트랜잭션 방식
- 작업을 바로 확정하지 않고 “예약(임시 확보)” 후 최종 확정하는 패턴
- Saga처럼 보상 트랜잭션을 사용하지만 실제 작업 전 자원을 먼저 예약(Try)하는 차이가 존재
- Saga는 작업 수행 후 실패 시 보상 트랜잭션을 수행하지만, TCC는 먼저 자원을 확보한 뒤 Confirm 또는 Cancel 수행
- 좌석 예약, 결제 승인, 포인트 차감 등 강한 정합성이 필요한 시스템에서 자주 사용
2. 성공 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[1] Client 요청
- 사용자가 예약 요청 전송
[2] Order Service (Try)
- 주문 임시 생성
- 상태: PENDING
[3] Payment Service (Try)
- 결제 금액 임시 승인(Hold)
- 실제 출금 아님
[4] Seat Service (Try)
- 좌석 임시 점유
- 다른 사용자 예약 제한
[5] Confirm 단계 시작
- 모든 서비스 Try 성공 확인
[6] Payment Service (Confirm)
- 실제 결제 확정
[7] Seat Service (Confirm)
- 좌석 최종 예약 확정
[8] Order Service (Confirm)
- 주문 완료 상태 변경
[9] 최종 완료
- 예약 및 결제 최종 확정
- 데이터 정합성 유지
3. 실패 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[1] Client 요청
- 사용자가 예약 요청 전송
[2] Order Service (Try)
- 주문 임시 생성
[3] Payment Service (Try)
- 결제 임시 승인(Hold)
[4] Seat Service (Try FAIL)
- 좌석 예약 실패 발생
[5] Cancel 단계 시작
- 하나의 서비스 실패 감지
[6] Payment Service (Cancel)
- 결제 승인 취소
[7] Order Service (Cancel)
- 임시 주문 취소
[8] 최종 실패
- 전체 예약 실패 처리
- 데이터 정합성 유지
8. CQRS + Event Sourcing
1. 개념
- CQRS(Command Query Responsibility Segregation)는 쓰기(Command)와 읽기(Query)를 분리하여 처리하는 패턴
- Event Sourcing은 데이터의 최종 상태를 저장하는 대신 발생한 이벤트(Event)를 저장하는 방식
- 데이터 변경 시 이벤트를 저장하고, 이를 기반으로 현재 상태를 재구성
- Write DB와 Read DB를 분리하여 조회 성능을 높이고 확장성을 확보 가능
- 주로 Kafka, Elasticsearch 등과 함께 사용되며 Eventual Consistency 기반으로 동작
2. 성공 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[1] Client 요청
- 사용자가 주문 생성 요청
[2] Command Service
- 주문 생성 처리
- OrderCreated Event 저장
- Event Store Commit
[3] Event 발행
- OrderCreated Event Broker 전달
[4] Query Service
- 이벤트 수신
- Read DB 반영 (Elasticsearch 등)
[5] Client 조회 요청
- 주문 목록/상세 조회 요청
[6] Query Service
- Read DB 조회
- 빠른 응답 반환
[7] 최종 완료
- 쓰기/읽기 데이터 동기화 완료
- 데이터 정합성 유지
3. 실패 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[1] Client 요청
- 사용자가 주문 생성 요청
[2] Command Service
- 주문 생성 처리
- OrderCreated Event 저장
- Event Store Commit
[3] Event 발행
- OrderCreated Event Broker 전달
[4] Query Service (FAIL)
- Read DB 반영 실패 발생
[5] 조회 요청
- 사용자가 조회 요청
- 최신 데이터가 누락될 수 있음
[6] Retry 수행
- 이벤트 재처리
- Read DB 재동기화 수행
[7] 최종 완료
- 조회 데이터 정상 반영
- 최종 데이터 정합성 유지
This post is licensed under CC BY 4.0 by the author.