|
| 1 | +### Chapter 09: 데이터 오너십과 분산 트랜잭션 |
| 2 | + |
| 3 | +### 개요 |
| 4 | + |
| 5 | +- 데이터 오너십 |
| 6 | + - 한 서비스가 어떠한 데이터를 소유할 지를 정의하는 부분 |
| 7 | + - 특정 테이블에 한 서비스만 접근가능하면 문제가 크게 없지만, 여러 서비스가 접근가능할 경우 (공동 오너십) 복잡해진다 |
| 8 | +- 단독 오너십 |
| 9 | + - 한 서비스만 테이블에 데이터를 쓸 수 있음 |
| 10 | + - 서비스와 테이블 간 경계 콘텍스트와 오너십이 명확하다 |
| 11 | +- 공통 오너십 |
| 12 | + - 대부분의 서비스가 동일한 테이블에 데이터를 같이 쓸 수 있는 상황 |
| 13 | + - 데이터가 공유되므로 내고장성, 확장성 등 데이터 공유 측면에서 매우 취약하다 |
| 14 | + - 하나의 데이터 쓰기 전용 서비스를 별도로 두어 해당 서비스에 테이블에 대한 권한을 위임하는 것이 대표적인 솔루션 |
| 15 | + - 또는 동기적으로 데이터를 쓰고 읽게끔 하는 방식도 있다 |
| 16 | +- 공동 오너십 |
| 17 | + - 공**동** 임에 주의 |
| 18 | + - 공통 오너십은 '대부분의 서비스' 가 테이블에 데이터를 쓰는 경우 (almost every) |
| 19 | + - 공동 오너십은 '대부분' 이 아닌 몇몇 서비스가 데이터를 쓰는 경우 (some) |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +### 테이블 분할 기법 |
| 24 | + |
| 25 | +- 테이블을 각 서비스가 담당하는 데이터 파트별로 분할하는 방법 |
| 26 | +- 이 기법을 통해 공동 오너십을 단독 오너십으로 전환할 수 있다 |
| 27 | + - 각 테이블을 하나의 담당 서비스만이 바라보게 하는 기법이므로 |
| 28 | +- 분할된 테이블 간의 데이터가 일관성을 갖추기 위해, 데이터 동기화 및 통신 방식을 고민해야 함 |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +### 데이터 도메인 기법 |
| 33 | + |
| 34 | +- 공유 데이터 도메인을 추가하는 것 |
| 35 | +- 여러 서비스가 데이터 오너십을 공유하는 게 아니고, 여러 서비스가 공유하여 사용하는 테이블들을 같은 데이터베이스 or 스키마에 넣어 컨텍스트를 넓히고 데이터 동기화가 수월하게끔 한다 |
| 36 | +- 데이터 구조 변경이 좀 더 까다로워지는 문제가 있다 |
| 37 | + |
| 38 | +--- |
| 39 | + |
| 40 | +### 대리자 기법 |
| 41 | + |
| 42 | +- 한 서비스에 테이블의 독점권을 주고 대리자로 만든 다음, 다른 서비스들은 이 대리자 서비스와 통신하여 데이터를 조작하는 방식 |
| 43 | +- 어떤 서비스를 대리자로 만들 지 고민해야 한다 |
| 44 | + - 주 도메인 우선: 해당 데이터의 주 도메인을 가장 잘 나타내는 서비스 |
| 45 | + - 보통 해당 메인 엔티티에 대부분의 CRUD 를 수행하는 서비스가 테이블의 주인이 됨 |
| 46 | + - 데이터 수정이 필요할 경우, 서비스간 통신이 필요함 |
| 47 | + - 동기 통신: 데이터 일관성이 보장되지만, 성능이 떨어짐 |
| 48 | + - 비동기 통신: 서비스 동작속도가 빨라지나 데이터는 최종 일관성만 보장됨 |
| 49 | + - 재고처리 등 업데이트 에러가 발생할 여지가 있음 |
| 50 | + - 운영 특성 우선: 성능, 확장성, 가용성 등 운영 아키텍처의 특성이 더 많이 필요한 서비스 |
| 51 | + - 데이터를 훨씬 빈번하게 건드리는 서비스가 대리자가 되므로, 데이터간 일관성 보장이 쉽다 |
| 52 | + - 허나 도메인 책임이 뒤바뀔 위험이 있어, 가급적이면 주 도메인 우선 방법을 사용하고 캐싱 등으로 성능을 올린다 |
| 53 | +- 서비스 커플링 (서비스간 통신) 이 필수적임 |
| 54 | + - 성능 / 내고장성 저하 |
| 55 | + |
| 56 | +--- |
| 57 | + |
| 58 | +### 서비스 통합 기법 |
| 59 | + |
| 60 | +- 같은 테이블을 바라보는 여러 서비스를 아예 통합해서 단독 오너십으로 전환 |
| 61 | +- 서비스가 커지므로 테스트 범위가 넓어지고, 배포 시 짊어져야 할 리스크가 커진다 |
| 62 | + |
| 63 | +--- |
| 64 | + |
| 65 | +### 분산 트랜잭션 |
| 66 | + |
| 67 | +- ACID 특성을 알아야 분산 트랜잭션을 알 수 있다 |
| 68 | + - Atomicity (원자성) |
| 69 | + - 한 트랜잭션에서 업데이트가 몇 번 발생하든, 하나의 덩어리로 취급되기 때문에 변경된 데이터는 한번에 커밋 or 롤백되어야 한다 |
| 70 | + - Consistency (일관성) |
| 71 | + - 트랜잭션 도중 데이터베이스가 일관되지 않은 상태 (무결성 제약조건 위배) 가 되지 않아야 한다 |
| 72 | + - 트랜잭션 도중에는 외래 키 등 일관성 제약조건을 위배할 수 없다 |
| 73 | + - Isolation (격리성) |
| 74 | + - 개별 트랜잭션은 서로 무관해야 하며, 서로가 서로를 볼 수 없게끔 격리되어야 한다 |
| 75 | + - Durability (내구성) |
| 76 | + - 트랜잭션을 커밋하고 성공 응답이 반환되면, 이후 어떠한 장애가 발생해도 해당 데이터는 모두 영구 보존되어야 한다 |
| 77 | +- 허나 분산 트랜잭션은 ACID 속성을 지원하지 않는다 (??) |
| 78 | + - 분산 트랜잭션에서는 대신 BASE 를 지원한다 |
| 79 | + - Basic Availability (기본 가용성) |
| 80 | + - 모든 서비스 또는 시스템이 분산 트랜잭션에 참여할 수 있으리라 기대하는 것 |
| 81 | + - Soft state (소프트 상태) |
| 82 | + - 분산 트랜잭션이 진행중이고, 원자적 비즈니스 요청이 미완료된 상태 |
| 83 | + - Eventual Consistency (최종 일관성) |
| 84 | + - 언젠가는 분산 트랜잭션의 모든 부분이 잘 완료될 것이고 모든 데이터가 잘 동기화될 것이라는 믿음 |
| 85 | + - 이 '언젠가' 소요 시간은 최종 일관성 패턴 유형과, 오류 처리 방법에 따라 달라진다 |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +### 최종 일관성 패턴 |
| 90 | + |
| 91 | +- 백그라운드 동기화 패턴 |
| 92 | + - 별도의 외부 서비스나 프로세스가 주기적으로 데이터를 체크해서 동기화하는 방법 |
| 93 | + - 최종 일관성이 지켜지는 시간은 프로세스를 감시하는 주체를 언제에 한번씩 구동시킬지에 따라 다르지만, 대개 가장 오래 걸린다 |
| 94 | + - 즉시 동기화할 필요 없는 데이터에 대해 사용 (예시: 고객 회원 탈퇴 후 해당 고객 정보 삭제) |
| 95 | + - 이 외부 서비스가 결국 테이블의 소유권 (읽기, 쓰기 권한) 을 갖고 있어야 동기화가 가능하기 때문에, 데이터와 서비스 간 경계 콘텍스트가 무너진다 |
| 96 | + - 분산 아키텍처 내부에서 엄격한 경계 콘텍스트를 만들어야 함 |
| 97 | + - 각 서비스가 소유한 테이블의 구조가 변경될 경우, 해당 외부 서비스와도 조정이 필요하므로 테이블을 건드리는 것 또한 쉽지 않다 |
| 98 | + - 비즈니스 로직 중복의 위험도 있음 |
| 99 | + |
| 100 | +- 오케스트레이티드 요청 기반 패턴 |
| 101 | + - 비즈니스 요청 처리 도중에 데이터 소스를 동기화하는 기법 |
| 102 | + - 동기화 주체인 오케스트레이터 (조정자) 서비스가 분산 트랜잭션을 관리한다 |
| 103 | + - 기존 서비스를 오케스트레이터로 지정할 경우, 해당 서비스는 자기 본업도 해야 하고, 오케스트레이터 일도 해야 한다 |
| 104 | + - 과부하가 걸리거나, 서비스 간 커플링이 고착화될 위험이 있음 |
| 105 | + - 각 서비스 상위에 관리자 서비스가 존재해서, 이 서비스가 데이터가 동기화되게끔 조정한다고 생각하면 됨 |
| 106 | + - 응답성보다 데이터 일관성 추구 |
| 107 | + - 시간이 오래 걸리더라도 데이터 일관성이 더 중요 |
| 108 | + - 에러 처리가 복잡해짐 |
| 109 | + - 특정 하위 서비스에서 오류 발생시, 오케스트레이터는 어떻게 대처해야 할 지 복잡해짐 |
| 110 | + |
| 111 | +- 이벤트 기반 패턴 |
| 112 | + - 인기가 제일 많고 믿음직스러움 (??) |
| 113 | + - 각 서비스들이 특정 액션 (고객 탈퇴 등) 을 이벤트 형태로 발행하여 게시하면, 이 이벤트를 구독하는 다른 서비스들이 이벤트에 따른 응답을 제공하는 방식 |
| 114 | + - 고객이 탈퇴했을 경우, 고객이 탈퇴했다는 이벤트를 이벤트 스트림 (or 메시지 토픽) 에 발행하여 알림 |
| 115 | + - 과금 서비스와 지원 서비스는 해당 이벤트를 수신하고, 그에 따른 뒤처리 수행 |
| 116 | + - 응답성이 우수하고, 서비스 간 커플링이 강하지 않으며, 적시에 일관성을 맞출 수 있다는 장점이 있음 |
| 117 | + - 역시나 에러 처리가 제일 까다로움 |
| 118 | + - 이벤트 처리 실패할 경우 |
| 119 | + - 이벤트 처리 중에 서비스가 죽을 경우 |
| 120 | + - 이벤트를 여러 번 전달하고, 그럼에도 실패할 경우 해당 이벤트를 데드 레터 큐에 밀어넣고, 관리자가 직접 대응할 수 있게끔 별도 처리 |
| 121 | + |
| 122 | +``` |
| 123 | +느낀점: 트랜잭션에 대한 배경지식이 충분하지 않을 경우 난감하다. 예전에 잠깐 겉핥기로 봤던 얕은 지식을 토대로 읽었다.. |
| 124 | +``` |
0 commit comments