티스토리 뷰

반응형

먼저 이번 장은 내용이 매우 깁니다. 책 주제에서 채팅시스템 설계와 같은 가장 많은 장으로써, 많은 내용을 다룹니다. 다만 내용이 자세하고 깊다기 보다 개념적으로 어루만지는 느낌이라 ... 보다 자세히 보기 위해선, 인터넷 자료나 데이터 중심 애플리케이션 설계라는 책도 같이 보는 것을 추천드립니다.

이번 장에서는 키-값 저장소 설계입니다. 키-값 저장소는 단일 키-값 저장소로 유지하면 충분하지 않아, 그 이상의 것을 이야기 하기 위해 나옵니다. 그 이상의 것은 분산형 키-값 저장소 입니다. 단일 키-값 저장소의 장점은 전부 메모리에 해시테이블로 저장하는 것인데 이 접근 법은 빠른 속도를 보장합니다. 하지만 모든 데이터를 메모리 안에 두는 것이 불가능하다는 약점이 존재 합니다. 다음과 같은 우회법이 있습니다. 데이터 압축자주 쓰이는 데이터만 메모리에 두고 나머지는 디스크에 저장 하는 방식입니다. 하지만 이러한 방식도 한 대의 서버로 부족한 때가 곧 찾아오기 때문에 분산형 키 -값 저장소 설계가 필요합니다.

이번 장에서는 분산형 키-값 저장소 설계에 대한 글입니다. 

분산형 키-값 저장소는 여러 서버에 키-값 저장소를 분산하는 방식입니다. 먼저 CAP 정리에 대해 알아봅시다.

CAP 정리데이터의 일관성(Consistency), 가용성(Availability), 파티션 감내(Partition tolerance) 세가지 요구 사항을 동시에 만족하는 것이 불가능 하다는 정리입니다. 

데이터 일관성은 분산 시스템에 접근하는 모든 클라이언튼는 어떤 노드에 접속했는지에 상관없이 동일한 데이터를 보게 되어야합니다.
가용성은 분산 시스템에 접속하는 클라이언트는 일부 노드에 장애가 발생하더라도 항상 응답을 받을 수 있어야 합니다.
파티션 감내는 파티션은 두 노드 사이에 통신 장애가 발생하더라도 시스템은 계속 동작 하여야 합니다.

CAP 정리에 따라 우리는 CA, CP, AP 설계를 시도하여야합니다. 하지만 실세계에서 네트워크 파티션은 반드시 발생하므로 CA 설계는 존재하지 않습니다.

CP 시스템: 일관성과 파티션 감내를 지원하는 키-값 저장소. 가용성을 희생한다.
AP 시스템: 가용성과 파티션 감내를 지원하는 키-값 저장소, 데이터 일관성을 희생한다.
CA 시스템: 일관성과 가용성을 지원한느 키-값 저장소. 파티션 감내는 지원하지 않는다. 그러나 통산 네트워크 장애는 피할 수 없는 일이므로, 파티션 감내는 필수적으로 감내할 수 있도록 설계해야한다. 따라서 CA 시스템은 존재 하지 않는다.

좀 더 자세히 살펴봅시다. 그림참조. 노드 n1, n2, n3가 존재한다고 하고, 네트워크 파티션이 없는 경우 n1에 기록되는 데이터는 n2, n3에 복제됩니다. 데이터 일관성과 가용성도 만족 되는 CAP 상태입니다. 그러나 실세계의 분산시스템은 네트워크 파티션을 피할 수 없습니다. n3에 장애가 발생한 경우, 일관성과 가용성 중 하나를 선택해야합니다. n1, n2에 기록한 데이터는 n3에 기록되지 않으며, n3를 통해 기록된 데이터도 n1, n2에 기록되지 않습니다. n1,n2와 n3는 각각의 오래된 사본을 유지하고 있을 겁니다.

가용성 대신 일관성을 선택한 CP 시스템 이라면, n1, n2에 쓰기 연산을 중단시켜야 합니다. 보통 은행권 시스템에서는 데이터 일관성을 절대 양보하지 않습니다. 계좌 최신정보를 출력하지 못한다면 큰 문제일 테니까요. 네트워크 파티션 때문에 일관성이 깨질 수 있는 상황이 발생한다면 이런 시스템에서는 해결될 때까지 오류를 반환하는 방식으로 대처할 것입니다.

일관성 대신 가용성을 선택한다면, 네트워크 파티션이 되어 오래된 사본을 유지하고 있더라도 읽기 요청이 들어올 때 다소 오래된 데이터를 반환할 것 입니다. 또한 n1, n2에 대해 계속 쓰기 연산을 허용할 것이고 파티션 문제가 해결 된 뒤에는 데이터를 n3에 전송할 것 입니다.

자 이번장에서 주로 볼 내용들을 나열 했습니다.

데이터 파티션, 데이터 다중화, 일관성, 일관성불일치 해소, 장애 처리, 시스템 아키텍처 다이어그램, 쓰기 경로, 읽기 경로에 대해서 살펴볼 것입니다. 다행히도 데이터 파티션과 데이터 다중화는 앞 장에서 살펴본 안정해시로 해소할 수 있습니다. 내용은 피피티 내용으로 갈음하겠습니다.

데이터 일관성에 대해서 살펴보겠습니다. 데이터 안정해시 에 분포된 서버에서 데이터 일관성을 지키려면 N, W, R 변수가 필요합니다. N은 사본 개수, W는 쓰기에 대한 정족수, R은 읽기에 대한 정족수 입니다. 정족수란, 어떤 것을 보장하기 위한 최소한의 수입니다. 아래 그림에서 N=3인 경우에 대한 그림을 살펴봅시다.

W=1인 경우, 최소 1대의 서버로부터 읽기 요청에 대한 응답을 받았다면 해당 데이터가 읽혔다고 판단하는 것입니다. 유의 할 것은 W=1인 경우와 N=1인 경우와 혼동하면 안됩니다. N=3인 경우 세대의 서버에 사본을 하지만 한 대에게 읽기 요청을 받으면 다소 빈약한 정족수 이라고 판단할 수 도 있습니다. 다만 정족수가 늘어난다면, 중재자의 응답속도는 응답속도가 가장 느린 서버에 의해 결정되므로 해당 부분에 부담이 있을 것 입니다.

W, R, N에 따른 일관성 보장은 다음과 같습니다.

R = 1, W = N : 빠른 읽기 연산에 최적화된 시스템
W = 1, R = N : 빠른 쓰기 연산에 최적화된 시스템
W + R > N : 강한 일관성이 보장됨 ( N = 3, W=R=2 )
W + R <= N : 강한 일관성이 보장되지 않음

여기서 강한 일관성의 성격이란 무엇일까요? 이를 보기 위해 일관성 모델에 대해 설명하여야 합니다.

일관성 모델은 키-값 저장소를 설계할 때 고려해야할 중요한 요소입니다. 
일관성이 강하면, 가장 최근에 갱신된 결과를 반환함을 보장합니다. 낡은 데이터를 절대 읽지 못한다는 것입니다. 약한 일관성일 수록 최근에 갱신된 결과를 반환받지 못할 수 있습니다. 최종 일관성은 약한 일관성의 한 형태로 갱신 결과가 결국에는 모든 사본에 반영되는 모델입니다.

강한 일관성을 달성하는 가장 쉬운 방법은, 쓰기 연산이 들어올 때 해당 데이터에 대한 읽기/쓰기를 모두 금지하는 것입니다. 이런 방법은 .. 고가용성 시스템에 적합하지 않습니다. 새로운 요청의 처리가 중단되기 때문입니다. 다이나모나, 카산드라 같은 저장소는 최종 일관성 모델을 택하고 있습니다. 이번장에서도 주로 최종 일관성 모델에 대한 설계를 할 것입니다. 최종 일관성 모델을 따를 경우 쓰기 연산이 병렬적으로 발생하면 시스템에 저장된 값의 일관성이 깨어질 수 있는데, 이 문제는 클라이언트가 해결해야합니다. 클라이언트 측에서 데이터 버전 정보를 활용하여 일관성이 깨진 데이터를 읽지 않도록 하는 기법에 대해 알아봐야합니다.

 

일관성 불일치 해소 기법으로 데이터 버저닝이 있습니다. 벡터 시계를 활용하여 저장하는 방법이 있습니다. 이 부분은 제가 PPT로 정리를 잘 해놓아 갈음하도록 하겠습니다.

장애처리는 대다수 대규모 시스템에서는 장애는 그저 불가피하기만 한 것이 아니라 아주 흔하게 벌어지는 사건입니다. 따라서 장애를 어떻게 처리할 것이냐는 중요한 문제입니다. 먼저 감지하는 방법에 대해 알아 볼 것입니다. 서버가 죽었다는 것을 알게 되는 것은 가십 프로토콜을 통해 구현할 수 있습니다. 가십프로토콜도 PPT로 갈음하도록 하겠습니다 ^^;;

이제 장애 감지를 하게 된다면 장애 처리에 대해 살펴볼 것입니다. 장애처리는 일시적 장애 처리와 영구적 장애 처리가 있습니다. 일시적 장애처리는 N 중의 W, R 정족수를 건강한 서버만 골라냅니다. 그리고 개 중에 다른 서버가 에러가 난 서버 대신 쓰기 및 읽기 기록을 대신하게 됩니다. 그리고 에러가 난 서버가 복구 되면 해당 정보를 넘겨줍니다. 이를 hinted handoff 기법이라고 합니다. 에러가 나지 않은 서버에 기록할 때는 hint 해놓고 나중에 handoff 한다는 것에서 이름이 지어진 것으로 보입니다.  

영구적인 장애 처리를 위해서는 먼저 서버들간 사본들을 비교해서 일관성이 망가진 부분만 처리를 해야할 것 입니다. 이때 사용 되는 것이 머클 트리 라는 자료구조인데, 해당 자료 구조를 이용하면 해시화 하여 데이터의 비교처리가 쉽습니다. 머클 트리란 다소 이름이 생소해서 어려워 보일 수 있으나, 그저 트리를 구성하되 트리 서브 루트에 해당 하위 트리를 데이터 기반으로 해시화 해둔 것입니다. 그래서 서브루트에는 하위 노드의 모든 정보를 해시화 해뒀으니 다른 데이터를 가지고 있는 서브 루트를 찾을 수 있다는 것 입니다. (데이터의 해시값으로 데이터 변조성을 체크하듯.sha256 등..) 책에서는 상세하게 설명해두었으나 어렵지 않은 부분이라 넘겼습니다.

데이터 센터 장애 처리는 여러 데이터 센터에 다중화 해두라는 것입니다.

 

이제 모든 것을 살펴보았으니 시스템 아키텍처 다이어그램을 그려봅시다. 클라이언트가 읽기 쓰기 연산을 요청하면 중재자로 선택된 서버는 프록시 역할을 수행하며 타 서버간에 W,R을 판단하여 응답을 줍니다. 모든 노드는 같은 책임을 지므로 SPOF는 존재하지 않습니다. 모든 노드는 클라이언트 API, 장애 감지, 데이터 충돌 해소, 장애 복구 메커니즘, 다중화 등의 역할을 갖습니다. 

이제 쓰기 경로와 읽기 경로에 대한 글이 됩니다. 읽기와 쓰기 요청이 들어올때 서버에서 어떻게 대응하는지 에 대한 글입니다. 카산드라의 구조를 차용했으므로 유의합니다. 쓰기 요청이 올 때 커밋로그를 남기며 SSTable에 기록합니다. 이 에 대한 내용은 데이터 중심 어플리케이션 설계 책을 읽으면 더 자세히 탐구 가능한데, 제가 이 책 포스팅이 끝나는대로 포스팅 하겠습니다. 

읽기 경로는 블룸필터를 이용하여 어떤 SSTable에 기록되었는지 찾아낸뒤 결과데이터를 반환합니다.

이상으로 요약입니다. PPT를 한번 살펴보십시오.

굉장히 많은 내용이 다루어졌으므로, 여기 까지 읽으시느라 고생하였습니다.

반응형