////
Search

26장 - 전자 지갑

생성일
2024/08/31 14:11
태그

1. 요구사항 정리

결제 플랫폼은 전자 지갑 서비스를 제공하여 고객이 예치금을 넣어두고 이를 통해 사용할 수 있도록 한다.
flowchart LR

은행 --> 결제시스템
결제시스템 --> 이커머스
Mermaid
복사
전자지갑
flowchart LR

전자지갑A--전송-->전자지갑B
Mermaid
복사
지갑 간 이체
전자 지갑 간 이체가 가능해야 함
1,000,000 TPS
99.99%의 안정성
트랙잭션이 가능해야 함
재현성이 있어야 함

1.1. 추정치 계산

이번 설계의 목표는 단일 노드가 처리할 수 있는 트랜잭션의 수를 늘리는 것
노드당 TPS
노드 수
100
20,000
1,000
2,000
10,000
200

2. 청사진 그리기

2.1. 인메모리 샤드

주키퍼와 레디스를 사용해서 높은 가용성과 안정성을 확보하자
레디스의 파티셔닝은 해쉬를 통해서 진행하자
주키퍼는 이런 파티션 구성 정보를 가지고 있도록 하자

2.2. 분산 트랜잭션

샤딩된 데이터에서 원자적으로 연산을 수행하는 방법
우선 레디스를 RDB로 변경해야 한다.

2.2.1. 2단계 커밋

저수준 방안으로 데이터베이스 자체에 의존하는 방안이다.
가장 일반적으로 사용되는 방법은 2PC다.
문제는 조정자가 SPOF가 될 수 있다.
또 다른 문제로는 2개의 데이터베이스가 락을 사용하기 때문에 성능이 별로다.

2.2.2. TC/C

TC/C(시도-확정/취소, Try-Confirm/Cancel)는 두 단계로 구성된 보상 트랙잰션
조정자는 모든 데이터베이스에 트랜잭션에 필요한 자원을 예약
모두 ‘예’ 응답시 조정자는 작업 확인을 요청
어느 하나라도 ‘아니요’응답 시 조정자는 모든 데이터베이스에 작업 취소를 요청함
2PC와 유사점이 많지만 다음의 차이점이 있다.
유형
첫 번째 단계
두 번째 단계 : 성공
두 번째 단계 : 실패
2PC
로컬 내 트랜잭션이 완료되기 전 상태
모든 로컬 트랜잭션 커밋
모든 로컬 트랜잭션 롤백
TC/C
모든 로컬 트랜잭션이 커밋되거나 취소된 상태
필요한 경우 새 로컬 트랜잭션 생성
이미 커밋된 트랜잭션의 되돌림 (undo)
즉 트랜잭션이 2번 생성되냐 한번 생성되느냐가 가장 큰 차이다.

2.2.3. 단계별 상태 테이블

TC/C 실행 중 서버가 다운되는 상황 방지를 위해 각 단계별 상태 정보를 트랜잭션 데이터베이스에 저장하자
같은 데이터베이스 내에 별도의 테이블을 만들어 위치시키는게 좋다.

2.3. 사가 (Saga)

개념 소개
모든 연산은 순서대로 정렬된다.
각 연산은 자기 데이터베이스에 독립 트랜잭션으로 실행됨
연산은 첫 번째부터 마지막까지 순서대로 실행된다.
한 연산이 완료되면 다음 연산이 개시
도중에 실패하면 실패한 연산부터 맨 처음 연산까지 역순으로 보상 트랜잭션을 통해 롤백됨
연산 실행 순서 조율 방법
분산 조율 = 사가 분산 트랜잭션에 관련된 모든 서비스가 다른 서비스의 이벤트를 구독해 작업하는 방식
중앙 집중형 조율 = 하나의 조정자가 모든 서비스가 올바른 순서로 작업을 실행하도록 조율
TC/C와 사가는 병렬이냐 순서대로 실행이냐에 따라서 실무에서 레이턴시 결정에 따라 선택 가능하다.

2.4. 이벤트소싱

1.
명령
a.
명령은 외부에서 전달된, 의도가 명확한 요청
b.
A에서 C로 이체하라는 요청은 명령이다.
c.
명령은 일반적으로 FIFO큐에 저장됨
2.
이벤트
a.
명령은 검증되기 전 팩트가 아님 = 유효하지 않을 수 있음
b.
이벤트는 검증된 팩트임 = 송금 명령하더라도 돈이 없으면 이벤트가 발생하지 않음
c.
하나의 명령에 여러 이벤트가 만들어질 수 있음
d.
이벤트도 일반적으로 FIFO큐에 저장됨
3.
상태
a.
이벤트가 적용될 때 변경되는 내용
b.
키-값 저장소로 저장됨
4.
상태기게
a.
상태기계는 이벤트 소싱 프로세스를 구동함
i.
명령의 휴효성을 검증하고 이벤트를 생성
ii.
이벤트를 적용하여 상태를 갱신
5.
재현성
a.
시작부터 계정 잔액을 알고 싶은 시점까지 이벤트를 재생하면 알 수 있다.
b.
이벤트 이력에서 계정 잔액을 다시 계산해 보면 잔액이 정확한지 확인 수 있다.
c.
새로운 코드에 동일한 이벤트 이력을 입력으로 주고 같은 결과가 나오는지 보면 된다.

2.6. 명령-질의 책임 분리 (CQRS)

이벤트 소싱 프레임워크의 클라이언트가 상태를 알도록 할 방법이 필요하다.
명령-질의 책임 분리
이벤트를 수신하는 외부 주체가 직접 상태를 재구축 할 수 있다.
CQRS에서는 상태 기록을 담당하는 상태 기계는 하나고, 읽기 전용 상태기계는 여러개 있을 수 있다.

3. 실제 설계

3.1. 고성능 이벤트 소싱

파일 기반의 명령/이벤트 기록
카프카 대신 로컬 디스크 저장을 고민해볼 수 있다.
추가는 순차적으로 매우 빠르다.
OS는 보통 순차적 읽기 및 쓰기에 연산이 엄청나게 최적화되어 있어 HDD에서도 잘 작동한다.
최근 명령을 메모리에 캐싱하는 방법도 고려해볼 수 있다.
구체적으로 mmap을 사용하면 로컬 디스크에 쓰는 동시에 최근 데이터는 메모리에 자동으로 캐시할 수 있다.
파일 기반 상태
RocksDB를 사용하여 파일 기반의 데이터베이스를 구축한다.
이는 LSM 자료구조를 사용하기 때문에 이는 쓰기 작업에 최적화 되어있다.
스냅숏
주기적으로 상태 기계를 멈추고 현재 상태를 파일에 저장한다면 시간을 절약할 수 있다.
스냅숏은 과거 특정 시점을 상태로 변경이 불가능하다.
과거 스냅숏의 날짜를 보고 이후 이벤트부터 처리를 시작하면 된다.
스냅숏은 거대한 이진파일이며 일반적으로 HDFS와 같은 저장소에 보관한다.