[NoSQL: 빅 데이터 세상으로 떠나는 간결한 안내서] 4장. 분산 모델
NoSQL은 대규모 클러스터에서 데이터베이스를 실행하기에 적합하다.
집합은 분산의 자연스러운 단위로 사용할 수 있으므로 수평 확장(여러 서버의 클러스터에서 실행하는 방법)과 잘 맞는다.
데이터 분산 방법
- 복제(replication) : 같은 데이터를 복사해 여러 노드에 분산
- 마스터-슬레이브(master-slave)
- 피어-투-피어(peer-to-peer)
- 샤딩(sharding) : 각 노드마다 다른 데이터
복제와 샤딩은 서로 직교하는 기법으로, 둘 중 하나만 사용해도 되고 둘 다 사용해도 된다.
요점
- 데이터를 분산하는 형식에는 샤딩과 복제 두 가지가 있다.
- 샤딩 : 여러 서버에 데이터를 나눔. 같은 데이터는 한 서버에서만 찾을 수 있음.
- 복제 : 여러 서버에 데이터를 복제. 같은 데이터를 여러 서버에서 찾을 수 있음.
- 샤딩, 복제를 동시에 사용하는 것도 가능
- 복제의 두 가지 형태
- 마스터-슬레이브
- 마스터 : 데이터의 원본 출처. 쓰기를 처리
- 슬레이브 : 마스터의 데이터를 동기화. 읽기를 처리
- 업데이트 충돌 발생을 줄인다.
- 피어-투-피어
- 모든 노드에 쓰리를 허용
- 데이터 복사를 동기화하기 위해 조율
- 한 노드에 모든 쓰기 부담을 지우지 않도록 해 단일 실패 지점이 생기지 않도록 함
4.1 단일 서버
데이터베이스를 단일 장비에서 실행하고 읽기와 쓰리를 모두 이 한 대의 장비로 처리
장점) 모든 복잡성이 사라진다. 관리하기 쉽다.
분산하지 않을 수 있다면 단일 서버가 최고의 선택
그래프 데이터베이스는 단일 서버 환경에서 가장 잘 동작
4.2 샤딩
데이터 저장소가 바쁜 이유 : 보통 많은 사람이 데이터 집합의 다른 부분에 접근하기 때문
샤딩 : 데이터의 다른 부분을 다른 서버에 두어 수평 확장을 지원
이상적으로 사용자마다 서로 다른 서버 노드를 사용하게 되어 부하가 균등하게 분산됨.
ex) 서버 10대가 있다면, 각 서버가 전체 부하의 10%씩 처리하면 된다.
하지만 이상적인 상황은 극히 드물다.
이상적 상황에 가까워지려면, 함꼐 접근되는 데이터는 같은 노드에 모여 있게 만든다.
이런 데이터 무더기를 여러 노드에 잘 배치해 최적의 데이터 접근성을 제공해야 한다.
문제점
1) 데이터를 어떻게 뭉쳐놓으면 한 사용자가 한 서버로부터 데이터를 얻게 할 수 있을까?
=> 집합 지향은 함께 접근되는 빈도가 높은 데이터를 모았으므로, 분산의 아주 좋은 단위
=> 특정 집합에 대한 접근이 물리적 위치에 기반을 둔다면, 접근이 발생하는 지역에 가까이 둔다.
ex) 보스턴에 사는 사람의 주문 데이터는 미국의 동부 데이터 센터에 위치 시킨다.
2) 어떻게 부하를 균등하게 분배할 수 있을까?
=> 부하는 시간에 따라 변한다. ex) 어떤 데이터는 특정 요일에 집중된다.
=> 어떤 경우는 순차적으로 읽힐 집합을 함께 두는 것이 유리
과거 샤딩 방식 : A~D, E~G 등 알파벳 순으로 샤드 분배.
- 단점 : 프로그래밍 모델이 복잡해짐. 분배 작업을 직접 코딩. 샤딩 불균형 초래. 균형 다시 맞출 때 또 코딩
=> NoSQL 에서는 자동 샤딩을 제공. 데이터에 접근할 때 올바른 샤드에 접근하도록 보장하는 책임을 데이터베이스가 짐
샤딩의 성능
읽기와 쓰기 성능을 모두 향상시킬 수 있음
복제를 (특히 캐시와 함께) 사용하면, 읽기 성능을 크게 높일 수 있지만 쓰기가 많을 경우 성능 향상이 거의 없음
샤딩은 쓰기에 대한 수평 확장 방법을 제공
샤딩만 단독으로 사용한 경우 복원력(resilience)은 거의 개선되지 않음.
노드가 실패하면 해당 노드에 있는 데이터를 사용할 수 없게됨.
물론 해당 샤드의 데이터를 사용하는 사용자만 제대로 서비스를 받지 못함.
클러스터는 보통 신뢰성이 덜한 저가 장비로 구성하므로 노드 하나가 실패하는 경우도 더 자주 발생.
처음부터 샤딩 사용을 목표로 하는 경우, 개발 시작 단계부터 클러스터에서 실행하는 것이 현명하다.
그렇지 않다면 단일 서버 설정에서 신중하게 서버를 늘리는 방식을 사용
4.3 마스터-슬레이브 복제
여러 노드에 데이터를 복제
마스터, 주(primary)노드 : 믿을 만한 출처. 데이터 업데이트를 처리할 책임을 진다. 읽기도 가능
슬레이브, 부(secondary) 노드 : 마스터 데이터를 복제. 읽기만 가능
복제 프로세스 : 업데이트 된 내용은 슬레이브로 전파
마스터-슬레이브 복제는 읽기 확장성에 도움이 되지만, 쓰기 확장성에는 도움이 되지 않음
장점 :
1) 읽기가 많이 발생하는 데이터 집합에 유리
=> 읽기 요청은 슬레이브에서 처리되고, 슬레이브 노드 추가시 더 많은 읽기 요청 처리 가능
=> 단, 업데이트를 처리하고 이를 전파하는 데는 여전히 마스터의 능력에 제한
2) 읽기 복원력 : 마스터 실패하더라도 슬레이브가 읽기 요청을 처리 가능
=> 역시 데이터 접근이 대부분 읽기일 경우 효과적
=> 슬레이브 하나가 즉시 새로운 마스터로 지정될 수 있으므로 복구 가능
3) 확장이 필요하지 않은 경우에도 유용하게 사용될 수 있음.
모든 읽기/쓰기 트래픽을 마스터가 처리하고, 슬레이브는 단지 핫 백업용으로 설정.
=> 단일 서버 구성의 편리함과 더 큰 복원력을 동시에 얻음
단점 :
1) 쓰기 트래픽이 많은 데이터 집합에 불리
2) 비일관성 :
변경 사항이 모든 슬레이브에 전파되기 전, 서로 다른 클라이언트가 서로 다른 슬레이브에서 읽어 서로 다른 값을 볼 수 있는 위험
최악의 경우는 한 클라이언트에서 자신이 쓴 데이터를 읽지 못하는 사태가 발생
핫 백업 용도로 사용하는 경우도 발생할 수 있음. (마스터가 실패하면 업데이트는 손실되므로)
이러한 문제는 어떻게 처리하는지 뒤의 '일관성'(5장) 에서 다룸
3) 마스터 실패에 대해서는 복원력을 제공하지 못함. 즉, 마스터는 여전히 병목이고 단일 실패 지점이 됨
마스터 지정 방식
수동) 클러스터를 구성할 때 노드 하나를 마스터로 설정
자동) 클러스터를 만들면 노드가 자신들 중 하나를 마스터로 선택. 자동 지정되므로 중단 시간을 줄일 수 있음
4.4 피어-투-피어 복제
피어-투-피어의 복제는 마스터를 두지 않으므로 마스터-슬레이브 구조의 병목, 단일 실패 지점에 대한 문제를 공략
모든 복제본의 가중치는 똑같음.
모든 노드에서 쓰기를 처리
노드 중 어느 것이 실패하더라도 데이터 저장소에 대한 접근이 중단되지 않음
노드를 추가해 쉽게 성능을 향상시키는 것도 가능
- 단점 : 일관성
다른 두 곳에 쓸 수 있다면, 두 사람이 동시에 동일한 레코드를 업데이트하려 하는, 쓰기 충돌 위험에 처할 수 있음
해결방법)
첫번째 방법) 데이터를 쓸 때 항상 복제본을 조율해 충돌이 발생하지 않도록 보장.
일관성을 챙기고, 가용성을 희생
쓰기를 위한 트래픽 비용은 늘어나지만 마스터와 같은 강력한 보장을 받을 수 있다.
모든 복제본이 쓰기에 동의할 필요는 없지만, 대다수가 동의해야 한다.
두번째 방법) 비일관적 쓰기를 허용하는 것이다.
가용성을 챙기고, 일관성을 희생
비일관적 쓰기를 병합하는 정책을 만들 수 있는 경우가 있는데, 이런 경우에는 어느 복제본에든 쓰기를 허용해 최대 성능 효과를 얻을 수 있다.
4.5 샤딩과 복제의 결합
마스터-슬레이브 복제와 샤딩을 모두 사용하면, 마스터가 여러 개 생기지만 각 데이터 항목은 마스터를 하나만 갖게 된다.
설정에 따라 어떤 노드를 특정 데이터에 대해서는 마스터로 하고, 다른 데이터에 대해서는 슬레이브가 되도록 할 수 도 있고, 마스터 또는 슬레이브 역할을 전담하도록 할 수도 있다.
피어-투-피어 복제와 샤딩을 사용하는 것은 칼럼 패밀리 데이터베이스에서는 흔한 전략.
피어-투-피어 복제의 좋은 시작점은 복제 인수를 3으로 해서, 각 샤드가 세 개 노드에 있도록 하는 것이다.
한 노드가 실패하면 해당 노드의 샤드는 다른 노드를 이용해 복구할 수 있다.