이번 포스트는 제 6장에 대해서 정리할 것입니다. 예측 내용은 비관계형 데이터베이스에 관한 내용입니다.
서론
키 값 저장소는 비 관계형 데이터베이스다. 이 저장소에 pk 값처럼 고유 식별자를 키로 가져야 하고 이러한 관계를 키 - 값 pair라고 한다.
형태
키 - 값
- 키는 유일해야 하고 값은 키를 통해서만 접근할 수 있다.
- 키는 텍스트, 해시 값 모두 가능하다. 짧을 수록 좋다.
- 값은 문자열 or 리스트, 객체
키 - 값을 쓰는 데이터베이스는 흔히 알고 있는 Redis, DynamoDB, memcached(단순 캐시용)가 있다.
설계 실습
put : 저장
get : 값 꺼내기
설계 실습에 앞서 키-값 크기는 10KB 이하, 큰 데이터를 저장, 높은 가용성, 확장성, 데이터 일관성 조절 가능, 응답 지연 시간 짧은 범위를 목표로 실습할 것이다.
단일 서버 저장소
1. 키-값 쌍을 메모리 해시 테이블로 저장
1-1. 데이터 압축
1-2. 자주 쓰이는 데이터만 메모리에 두고 나머지는 디스크 저장.
이제 분산 서버로 확장할 것이다.
분산 서버 저장소
CAP 정리.

cap 정리란 데이터 일관성, 가용성, 파티션 감내를 동시에 만족하는 분산 시스템을 설계하는 건 불가능하다는 이론이다. 즉, 셋 중 하나는 반드시 희생되어야 한다는 의미이다.
데이터 일관성 : 어떤 노드를 접속 하든지 일관된 데이터를 보는 것.
가용성 : 어떤 노드에 장애가 발생해도 항상 응답을 받을 수 있는 것.
파티션 감내 : 두 노드의 통신 장애가 생겨도 시스템은 계속 동작되어야 하는 것.
분산 시스템의 데이터는 여러 노드에 복제되어 있다.
n1
n2 n3
노드가 이렇게 존재할때, n3에서 오류가 발생하면 n3의 데이터는 n1, n2 는 업데이트 되지 못한 채 존재하게 된다.
CP : 일관성 - 파티션 감내
-> 가용성 대신 일관성을 선택
-> n1, n2에 대한 쓰기 연산을 중단
-> n3이 복구될 때까지 일부 기능 중단
-> 은행 시스템에서 데이터 정확성이 절대적으로 중요할 경우
AP : 가용성 - 파티션 감내
-> 오래된 데이터를 반환할 위험이 있더라도 계속 쓰기 연산을 허용
-> 일시적으로 노드 간 데이터 불일치가 발생
-> n3가 복구된 후, 새 게시물 데이터가 n3에 동기화
-> 콘텐츠 플랫폼 서비스 경우 적합
CA : 일관성 - 가용성
시스템 컴포넌트
- 데이터 파티션
-> 데이터를 여러 서버에 고르게 분산
-> 노트가 추가, 삭제될 때 데이터 이동 최소화
- 데이터 다중화
-> 데이터를 N개 서버에 비동기적으로 다중화
-> 시계 방향으로 돌면서 서버에 데이터 사본 보관
- 데이터 일관성
-> 여러 노드에 다중화된 데이터는 동기화 되어야 한다.
-> 정족수 합 프로토콜 사용하여 읽기, 쓰기 연산에 일관성 보장
- N: 총 복제본 수
- W: 쓰기 연산 정족수, 쓰기 연산이 성공한 것으로 간주되려면 적어도 W개의 서버로부터 연산이 성공했다는 응답을 받아야 한다.
- R: 읽기 연산 정족수, 읽기 연산이 성공한 것으로 간주되려면 적어도 R개의 서버로부터 연산이 성공했다는 응답을 받아야 한다.
예를 들어 N=3, W=1의 의미는 쓰기 연산이 성공했다고 판단하기 위해서는 중재자는 최소 한대 서버로 부터 쓰기 성공 응답을 받아야 한다는 뜻이다. 따라서 n1으로부터 성공 응답을 받았다면 n0, n2로 부터의 응답은 기다릴 필요가 없다.
-> 중재자는 클라이언트와 노드 사이의 프락시 역할
W, R, N을 정하는 방법 :
W, R, N을 정하는 것은 응답 지연과 데이터 일관성 사이의 타협점을 찾는 과정과 같다.
- R=1, W=N: 빠른 읽기 연산에 최적화된 시스템
- W=1, R=N: 빠른 쓰기 연산에 최적화된 시스템
- W+R>N: 강한 일관성이 보장됨(보통 N=3, W=R=2)
- W+R<=N: 강한 일관성이 보장되지 않음
일관성 모델
- 강력한 일관성(Strong Consistency): 가장 최근에 갱신된 결과를 반환. 늘 최신 데이터를 반환.
- 방법: 모든 사본에 현재 쓰기 연산의 결과가 반영될 때 까지 해당 데이터에 대한 읽기/쓰기를 금지
- 문제: 고가용성 시스템에는 적합 x
- 약한 일관성(Weak Consistency): 읽기 연산은 가장 최신 데이터를 반환하지 못할 수 있다.
- 최종 일관성(Eventual Consistency): 약한 일관성의 한 형태로 업데이트 후에 결국에는 일관성 있는 상태로 반영된다.
- 문제: 쓰기 연산이 병렬적으로 발생하면 시스템에 저장된 값의 일관성이 깨질 수 있다.
- 해결 방법: 클라이언트측에서 데이터의 버전 정보를 활용해 일관성이 깨진 데이터를 읽지 않도록한다.
- 일관성 불일치 해소(inconsistency resolution) (데이터 버저닝, 벡터시계)
데이터 버저닝은 각 데이터 업데이트에 고유한 버전 번호를 부여한다.
-> 문제 : 버전 1, 버전2의 값이 다를 때
-> 해결 : 벡터시계
백터시계는 [서버, 버전]의 순서쌍을 데이터에 함께 저장하는 것
-> 문제 : 1. 충돌 감지, 해소하는 로직이 클라이언트에 들어가 있음. 구현 복잡 2. [서버 : 버전] 순서쌍 개수가 매우 빠르게 늘어남
-> 해결 : 길이에 임계치 설정. 오래된 순서쌍을 백터 시계에서 제거. (충돌 버전 선후관계기 비정확해질 수 있고 해소 과정의 효율성이 낮아지지만 아직 그런 문제를 발견한 적이 없다고 함. )
- 장애 처리
- 장애 감지 (Failure Detection): 두 대 이상의 서버가 장애를 보고해야 실제 장애로 간주.
- 장애 해소 (Failure Resolution)
- 영구 장애 처리(Failure Resolution): 근본적인 해결책 필요
장애 감지
- 멀티캐스팅
- Gossip Protocol: 가십 프로토콜은 분산형 장애 감지 솔루션이다. 각 노드가 주기적으로 다른 노드에게 데이터를 노낸다. 노드가 예상 시간 안에 데이터를 보내지 않으면, 다른 노드들은 그 노드가 장애(오프라인) 상태인 것으로 간주한다.
일시적 장애 처리
Gossip Protocol로 장애를 감지한 시스템은 가용성을 보장하기 위해 필요한 조치를 해야한다.
방법:
엄격한 정족수 : 읽기 쓰기 연산 금지
느슨한 정족수 : 읽기, 쓰기 연산할 서버를 고른다.
장애 서버로 가는 요청은 다른 서버가 맡아서 처리하고 변경사항은 서버가 복구 되었을 때 일괄 빈영한다. 이를 위해 임시 서버는 힌트를 남겨 두어야 한다. (임시 위탁)
영구 장애 처리
방법:
- Anti-Entropy: 시스템의 다른 부분 간에 데이터 사본을 주기적으로 동기화하고 갱신한다. 사본 간의 일관성이 망가진 상태를 탐지하고 전송 데이터 양을 줄이기 위해 Merkle Trees가 사용된다.
- Merkle Trees: 머클트리의 목적 은 빠른 검색이 아니라 데이터의 간편하고 확실한 인증 을 위해 사용하며 SHA-256(해시함수)를 사용한다.
- 시스템 아키텍처 다이어그램
분산 키-값 저장소의 전체적인 구조는 다음과 같다.
- 클라이언트는 API(get, put)를 통해 시스템과 통신
- 중재자(Coordinator)는 클라이언트와 노드 사이의 프록시 역할
- 노드들은 안정 해시 링 위에 분포
- 시스템은 완전히 분산되어 있어 노드의 자동 추가/삭제가 가능
- 데이터는 여러 노드에 다중화되어 저장
- 단일 장애점(SPOF)이 없는 구조
- 쓰기 경로(카산드라)
- 쓰기 요청이 커밋 로그 파일에 기록된다.
- 데이터가 메모리 캐시에 기록된다.
- 메모리 캐시가 가득차거나 사전에 정의된 어떤 임계치에 도달하면 데이터는 디스크에 있는 SSTable에 기록된다. SSTable은 Sorted-String Table의 약어로, <키, 값>의 순서쌍으로 정렬된 리스트 형태로 관리하는 테이블이다.
- 읽기 경로
읽기 요청을 받은 노드는 데이터가 메모리 캐시에 있는지 살핀다.
메모리캐시에 없을 때 디스크에서 가져오기 (블룸 필터 이용) -> SSTable에 키가 보관되어 있는지 알나 낸 후 데이터 반환
'시스템 아키텍쳐 스터디' 카테고리의 다른 글
| 제 5장 - 안정 해시 설계 (0) | 2025.09.28 |
|---|---|
| 제 4장 - 처리율 제한 장치의 설계 (1) | 2025.08.31 |
| 제 2장, 3장 - 시스템 설계 면접 (1) | 2025.08.24 |
| 제 1장 - 사용자 수에 따른 규모 확장성 (5) | 2025.08.17 |