현대 분산 시스템의 문제점과 이를 해결하기 위한 해결책,한계 등에 대한 이론 및 구성을 소개하고 데이터 중심 어플리케이션 설계를 뒷받침하는 개념을 소개하는 책
-
기본 개념
- 시스템 신뢰성
- 무언가 잘못(결함 발생)되더라도 지속적으로 올바르게 동작함
- 장애는 시스템이 멈춘 경우지만 결함은 사양에서 벗어난 시스템의 한 요소로 여겨진다
- 시스템 확장성
- 증가한 부하에 대처하는 시스템 능력
- 응답 시간을 살펴볼 때에는 중앙값(p50), 상위 95,99 분위(p95,p99)와 같은 상위 지표도 중요하다
- 시스템 유지보수성
- 운용성, 단순성, 발전성을 지닌 시스템이 유지 보수에 용이하다
-
데이터 모델과 질의(Query) 언어
- 선언형 언어(Query)는 명령형 언어보다 병렬 실행에 적합하다
- 스키마
- 쓰기 스키마: 쓰여진 모든 데이터가 스키마를 따르고 있음을 보장 → RDB
- 읽기 스키마: 데이터 구조는 암묵적이고 데이터를 읽을 때 해석된다 → NO-SQL
- RDB 특징
- 대다수의 케이스에 잘 들어맞지만 특성은 약하다
- 조인, 일대다, 다대다 관계를 No-SQL 보다 더 잘 지원한다
- No-SQL 특징
- 스키마 유연성, 지역성에 기인한 더 나은 성능
- 문서 간 관계가 거의 없는 경우 용이하다
- 항목이 특정 사유로 동일한 구조가 아닐 때 매우 유리하다
- 그래프 데이터베이스 특징
- 상호 연결이 많은 데이터를 매우 잘 지원한다
- 발전성이 좋아 데이터 구조의 변경이 좀 더 용이하다
- 정점(vertex, entity)와 간선(edge, arc)로 표현되는 데이터베이스
-
저장소와 검색
- 색인(INDEX)
- 쓰기 성능과 읽기 성능의 트레이드 오프
- 방식
- Hash 방식: Key-Value 형태의 index를 생성하는 방식. 주로 Primary Key에 사용
- 클러스터링 색인의 경우 색인 안에 모든 로우를 저장한다
- 보조 색인: 중복을 허용하며 색인의 각 값에 해당하는 로우 식별자 목록을 저장하는 색인
- 커버링 색인: 보조 색인의 단점을 개선하여 식별자 목록만이 아닌 일부 칼럼을 저장하는 방식의 색인
- 다중(결합) 색인: 하나의 키에 여러 필드를 결합하여 색인
- Trie: 각 키를 특정 형태에 따라 깊이를 지정하여 저장하는 방식의 색인 ( EX: A-AB-ABC-ABCD )
- 추가 전용 로그 ( 로그 세그먼트 )
- 예전 값을 새로운 값으로 덮어쓰지 않고 마지막에 추가하여 파일을 갱신하는 방법
- 속도가 빠르고, 동시성 보장/ 고장 복구가 훨씬 간단하다
- 병합(Compaction)을 통해 조각화되는 문제를 회피할 수 있다
- SS ( Sorted String ) Table
- Hash 방식으로 만들어지는 로그 세그먼트는 정렬이 문제가 될 수 있다
- 이를 해결하기 위해 키의 순서로 이루어진 세그먼트로 병합하는 Table
- 장점
- 로그 세그먼트를 정렬하면서 압축하여 희소 색인(sparse index)을 생성할 수 있다
- 디스크 공간을 절약하고 I/O 대역폭 사용을 줄여 성능 향상을 얻을 수 있다
- 단점
- 정렬과 트리의 균형 유지를 위한 비용이 발생한다
- LSM(Log-Structured Merge) 트리
- 정렬된 파일 병합과 컴팩션 원리를 기반으로 하는 방식
- 키가 존재하지 않는 경우 성능이 좋지 않아 블룸 필터 를 추가적으로 사용한다
- 압축 전략
- size-tiered: 새롭고 작은 SS 테이블을 오래되고 큰 SS 테이블에 지속 병합
- leveled compaction: 범위에 따라 SS 테이블의 level을 구분하고 level에 따라 점진적인 병합
- B-Tree
- SS 테이블처럼 정렬된 노드를 가진 B-Tree
- 고정 크기의 블록/페이지로 나누고 하나의 페이지에 읽기/쓰기를 하는 방식
- 쓰기 전 로그 ( Write-Ahed Log = Redo Log )
- 트리 페이지에 변경 내용을 적용하기 전에 변경 사항을 기록하는 로그
- 데이터베이스 고장 시 복구/ 롤백을 위해 사용된다
- LSM Tree Vs B-Tree
- 쓰기 처리량은 LSM 트리가 더 빠르다 → 쓰기 증폭이 더 낮고 순차성이기 때문
- 읽기 처리량은 B 트리가 더 빠르다 → Tree 방식을 이용하여 탐색이 더 빠름
-
스키마 부호화(표현)와 발전(호환성)
- 부호화(직렬화, 마샬링): 인 메모리 표현에서 바이트열로 변환
- 복호화(역직렬화, 언마샬링): 바이트 표현에서 인 메모리 형태로 변환
- 아브로(Avro)
- 쓰기, 읽기 스키마가 동일하지 않아도 호환 가능하면 사용 가능
- 스키마가 있어 문서화가 유용하고 이로 인해 필드 이름의 생략이 가능하다
- 요청은 하위 호환성이 필요하고, 응답은 상위 호환성이 필요하다
-
분산 데이터
- 메모리 비 공유 아키텍처에서 데이터에 대한 성능/내 결함성을 얻기 위해 데이터를 분산하는 방식
-
복제
- 같은 데이터의 복사본을 다른 위치의 여러 노드에 유지한다
- 동기식 VS 비동기 식
- 거의 대부분의 복제 방식은 비동기를 이용하고 있다
- 동기식에서는 하나의 팔로워만 실패하더라도 내결함성을 잃기 때문에 잘 사용되지 않는다
- 비동기 복제의 문제점
- 리더보다 팔로워가 뒤쳐지는 경우 팔로워에 대한 질의는 과거 데이터를 보여줄 수 있다
- 해결방법
- 단조 읽기(monotonic read): 위 현상을 해결하기 위한 방법으로 각 사용자의 읽기를 항상 같은 서버로 라우팅하는 방식을 이용한다
- 일관된 순서로 읽기: 일련의 쓰기가 특정 순서로 발생한다면 이 쓰기를 읽는 모든 사용자는 같은 순서로 쓰여진 내용을 보게 됨을 보장하는 방법
- 복제 로그 구현 방식
- 복제 알고리즘
- 쓰기 충돌
-
파티셔닝 ( 샤딩 )
-
트랜잭션
- 데이터 중심 어플리케이션: 데이터가 주요 도전 과제인 어플리케이션
- 계산 중심 어플리케이션: CPU 사이클이 도전 과제인 어플리케이션