-
분산 시스템의 난제
- 비 결정성을 지니기 때문에 여러 문제가 발생한다
- 노드 자원 상의 문제는 대부분은 해결이 가능하지만 하기 자원들은 어렵다
- 네트워크
- 신뢰성이 적어 타임 아웃을 기본으로 적용해야 한다. 그러나 이 역시 근본적인 문제를 해결 할 수 없다
- 큐 대기, 장비 문제 등으로 인해 지연이 발생할 가능성이 높다
- 시간
- NTP ( 네트워크 시간 프로토콜) 로 서버 시간을 동기화 가능하지만 여전히 문제(실패)는 발생할 수 있다
- 리더 선출
- 리더 선출 방식을 이용하는 시스템의 경우 두 노드가 자신을 리더라고 생각하는 스플릿 브레인 현상이 발생할 수 있다
- 해결 방법
- 펜싱 토큰: 리더로 선출될 때 순차적으로 증가하는 토큰을 발급하고, 클라이언트에서 매번 토큰을 전송한다. → 토큰의 값이 서버와 다르면 실패 처리 한다
- 비잔틴 결함
- 악의적인 공격자가 네트워크를 방해하여 노드의 신뢰성을 저하시키는 공격
- 사용자의 입력을 철저하게 검증해야 한다
- 시스템의 타이밍 모델
- 동기식: 네트워크 지연, 프로세스 중단, 시계 오차에 모두 제한이 있는 모델
- 부분 동기식: 대부분의 시간에는 동기식이나 때때로 결함에 의해 한계치를 초과하는 시스템. 가장 현실적이고 가장 유용하다
- 비 동기식: 어떤 가정도 없는 모델
-
일관성과 합의
- 분산 시스템에서 가장 중요한 추상화는 합의 이다
- 직렬성: 트랜잭션이 어떤 순서에 따라 실행되는 것을 보장
- 선형성
- 시스템에 데이터 사본이 하나 뿐인 것처럼 보이게 만들어 최종 일관성을 보장하는 방식
- 읽기가 최신 값을 반환한다면 모든 후속 읽기도 최신 값을 반환해야 한다 → 최신성 보장
- 단일 리더, 합의 알고리즘을 사용하는 경우를 제외하고 구현이 어렵다
- 선형성이 필요 없는 어플리케이션은 네트워크 문제에 더 강인하다
- 인과성
- 선형성이 전체의 순서를 보장하는 것이라면, 인과성은 서로 연관이 있는 연산에 대해 부분 순서를 보장한다
- 구현 방법
- 일련번호나 타임스탬프를 이용하여 이벤트의 순서를 정하는 방식을 주로 이용한다
- 램포트 타임스탬프: (카운터, 노드ID )를 쌍으로 가지는 타임스탬프. 카운터가 같다면 노드ID가 큰 것이 더 나중으로 여겨진다
- 전체 순서 브로드캐스트
- 리더 장애나 리더 수용량을 넘어서는 트래픽에서 연산의 전체 순서를 정하는 문제
- 모든 노드에게 메시지가 정확히 한 번, 같은 순서로 전달되어야 한다
- 합의 알고리즘으로 직결된다
- 합의 알고리즘
- 하나 또는 그 이상의 노드들이 값을 제안하고 그 중 하나를 결정하는 알고리즘
- 단일 리더 시스템에서 주로 사용된다.
- 속성
- 균일한 동의: 어떤 두 노드도 다르게 결정하지 않는다
- 무결성: 어떤 노드도 두 번 결정하지 않는다
- 유효성: 한 노드의 결정은 그 노드에서 제안된 것이다
- 종료: 죽지 않는 노드는 반드시 값을 결정한다
- 2PC (two phase commit )
- 모든 연관 노드가 커밋되거나 롤백되는 것을 보장하는 알고리즘
- 트랜잭션 코디네이터를 이용하여 모든 노드가 커밋됨을 보장한다
- 코디네이터의 장애에 매우 취약하며, 성능이 매우 나쁘다 → 내결함성 구현에 좋지 않다
-
배치 처리
- 배치에서 조인은 데이터 셋 내 모든 연관 관계를 다룬다는 뜻이다
- 입력 데이터 셋이 한정된다 → 무한할 수 없다
- 입력에 대한 처리가 완료되고 중간 데이터가 생성되어야 다음 처리기를 호출 할 수 있다
-
스트림 처리
- 스트림: 시간 흐름에 따라 점진적으로 생상된 데이터
- 고정된 시간 조각의 배치 처리 대신 이벤트가 발생할 때마다 처리하는 방식
- 메시징 시스템 선택
- 메시지를 처리하는 비용이 비싸고 순서가 중요하지 않다면 JMS/AMQP 방식
- 처리량이 많고 순서가 중요하다면 로그 기반 접근 ( ex: Kafka ) 방식
- 윈도우
- 스트림 처리에서 집계 시간의 간격
- 방식
- 텀블링: 고정 길이의 크기.
- 홉핑: 작은 크기의 텀블링 윈도우를 중첩하여 원하는 길이의 윈도우를 만듬
- 슬라이딩: 각 시간 간격 사이에 발생하는 모든 이벤트를 포함하는 윈도우. 이벤트를 저장하고 윈도우가 필요할 때 생성되는 방식. 오래된 이벤트는 적출하여 제거한다
- 세션: 사용자의 세션의 시작과 끝에 따라 윈도우의 크기가 결정된다
- 조인 유형
- 스트림-스트림 조인: 일정 윈도우 내에서 발생하는 스트림의 조인
- 스트림-테이블 조인: 한 쪽은 이벤트, 다른 하나는 데이터베이스의 변경 로그(로컬 사본)로 구성
- 테이블-테이블 조인: 둘 다 데이터베이스의 변경 로그(로컬 사본)로 구성
-
미래에는.. ( 저자 주관 )
- 데이터 통합
- 조직 전체의 데이터 플로우를 보기 위한 도구의 결합이 필요하다
- 이벤트 로그를 이용하면 결정적이고 멱등적이여서 결함에서 복구하기 용이하다
- 람다 아키텍처
- 스트림 처리자와 배치 처리자를 따로 두어 근사치와 신뢰성 있는 데이터 둘 다 얻는 방식
- 단점
- 같은 로직을 스트림/배치 처리자 각각 유지해야 한다
- 복잡한 연산 구현이 어렵다
- 증분에 대한 일괄처리 구현이 어렵다
- 이를 해결하기 위해 Kappa 아키텍처와 같은 통합 처리 아키텍처가 등장했다
- 데이터베이스 언 번들링
- 연합 데이터베이스
- 읽기를 통합하여 여러 데이터베이스에서 단일 질의 언어로 읽기를 구현한다
- 언 번들링 데이터베이스
- 통일된 저수준 API를 통해 쓰기를 통합한다
- 필요한 팀에서 필요한 데이터를 바로 제공받을 수 있다
- 어플리케이션 설계
- 레코드 시스템: Source Of Truth(진실의 근원) 을 생성해 내는 시스템
- 파생 데이터 시스템: 다른 시스템에 존재하는 데이터를 가져와 특정 방식으로 변환하고 처리하는 시스템
- 핫 키(린치핀 객체): 불균형한 활성 데이터베이스 레코드 → ex) 조회가 매우 많은 데이터
- DAG( 비 순환 방향 그래프): 데이터 플로우 엔진에서 작업 연산자를 배열하는 방식