*<가상 면접 사례로 배우는 대규모 시스템 설계 기초> 을 참고하여 작성한 게시물입니다.
키-값 저장소는 키-값 데이터베이스라고도 불리는 비관계형 데이터베이스다. 이 저장소에 저장되는 값은 고유 식별자(identifier)를 키로 가져야한다. 키와 값 사이의 이런 연결 관계를 "키-값" 쌍(pair)라고 지칭한다. 키-값 쌍에서의 키는 유일해야하며, 해당 키에 달린 값은 키를 통해서만 접근할 수 있다. 키는 일반 텍스트일 수도 있고 해시 값일수도 있는데, 성능 상의 이유로 키는 짧을 수록 좋다. 값은 문자열일수도, 리스트일수도, 객체(object)일수도 있다. 무슨 값이 오든 상관하지 않는다. 가장 널리 알려진 것으로 Amazon Dynamo, memcached, redis 등이 있다.
put(key, value):키-값 쌍을 저장소에 저장한다.
get(key): 인자로 주어진 키에 매달린 값을 꺼낸다.
이 연산을 지원하는 키-값 저장소를 설계해보자.
가장 직관적인 방법은 키-값 쌍 전부를 메모리에 해시 테이블로 저장하는 것 그러나 이는 빠른 속도를 보장하기는 해도, 모든 데이터를 메모리 안에 두는 것이 불가능할 수도 있다는 약점을 가지고 있다. 이를 해결하기 위한 개선책으로는 1)데이터 압축, 2)자주 쓰는 데이터만 메모리에 두고 나머지는 디스크에 저장 이 있다. 그러나 이렇게 해도 한 대 서버로는 부족한 때가 찾아온다. 많은 데이터를 저장하려면 분산 키-값 저장소를 만들 필요가 있다.
이는 분산 해시 테이블이라고도 불린다. 분산 시스템을 설게할때는 CAP 정리(Consistency, Availability, Partition Tolerance theorem)을 이해하고 있어야 한다.
키-값 저장소는 앞서 제시한 세가지 요구사항 중 어느 두가지를 만족하느냐에 따라 다음과 같이 분류할 수 있다.
예시를 보면 다음과 같다. 분산 시스템에서 데이터는 보통 여러 노드에 복제되어 보관되는데, 세 대의 복제 노드 n1,n2,n3에 데이터를 복제하여 보관한다고 하자. 이상적 환경이라면 네트워크가 파티션되는 상황은 저대로 일어나지 않아서, n1에 기록된 데이터는 자동적으로 n2,n3에 복제되어 데이터 일관성과 가용성도 만족된다. 그러나 실세계의 분산시스템은 파티션 문제를 피할 수 없다. 그리고 파티션 문제가 발생하면 일관성, 가용성 사이 중 하나를 선택해야 한다. n3에 장애가 발생하여 n1, n2와 통신할 수 없다면, 클라이언트가 n1, n2에 기록한 데이터는 n3에 전달되지 않고 n3에 기록되었으나 아직 n1, n2로 전달되지 않은 데이터가 있다면 n1,n2는 오래된 사본을 갖고 있을 것이다.
CP 시스템이라면 세 서버 사이에 생길 수 있는 데이터 불일치 문제를 피하기 위해 n1,n2에 대해 쓰기 연산을 중단시켜야 하는데, 그러면 가용성이 꺠진다. 은행권은 보통 데이터 일관성을 양보하지 않는다. 예로 온라인 뱅킹 시스템이 계좌 최신 정보를 출력하지 못하면 큰 문제일 것이다. 네트워크 파티션 떄문에 일관성이 깨질 수 있는 상황이 발생하면 이런 시스템은 상황 해결시까지 오류를 반환해야 한다.
AP 시스템이라면 낡은 데이터를 반환할 위험이 있더라도 계속 읽기 연산을 허용해야하는데, 아울러 n1, n2는 계속 쓰기 연산을 허용할 것이고, 파티션 문제가 해결된 후에 새 데이터를 n3에 전송할 것이다.
분산 키-값 저장소를 만들 때는 그 요구사항에 맞도록 CAP 정리를 적용해야 한다.
구현에 사용될 핵심 컴포넌트 및 기술들이다.
데이터 파티션
데이터 다중화(replication)
일관성(consistency)
일관성 불일치 해소(inconsistency resolution)
장애 처리
시스템 아키텍처 다이어그램
쓰기 경로(write path)
읽기 경로(read path)