데이터베이스

분산 키-값 저장소에서 고려해야할 점

hayz 2025. 1. 23. 20:37

아래 내용은 "가상면접 사례로 배우는 대규모 시스템 설계기초" 의 6장인 '분산 키-값 저장소 설계' 의 내용을 정리했습니다. 

 

만약, 우리 서비스가 키-값 저장소를 사용하려 하는데 아래와 같은 요구사항이 필요하다고 한다.

  • 큰 데이터를 저장할 수 있어야 한다. 
  • 높은 가용성을 제공해야 한다. 장애시 빠르게 응답해야 한다. 
  • 높은 확장성을 제공해서, 트래픽양에 따라 자동적으로 서버 증설/삭제가 이뤄져야 한다. 
  • 데이터 일관성 수준은 조정 가능해야 한다. 
  • latency 가 짧아야 한다. 

 

위와 같은 요구사항을 만족시켜야 할때, 우선 아래와 같은 선택지가 있다. 

  1. 단일 저장소 
  2. 분산 저장소

하지만.. 단일 저장소는 빠른 응답을 위해 메모리에 올려두는 방식을 선택할 수 있겠지만, 많은 요청을 한번에 감당하거나 장애시 대응에는 한계가 있기 때문에 분산저장소에 대해서 고민해봐야 한다. 

 

 

데이터 파티션

우선 분산 시스템을 설계하기 위해서는 기본적으로 데이터가 각 저장소에 분산으로 배치되어있어야 한다는 것이 가정되어야 한다. 이 분산된다는 것은 데이터의 '키' 값을 기준으로 배치되어야할 노드로 분산해둬야 한다는 의미인데, 분산 키-값 저장소 중에서 특히 'dynamoDB' 는 Consistent hash(안정 해시)를 사용하고 있다. 

 

안정 해시는 링 형태의 구조 위에서 해시값에 대응하는 노드를 찾아가는 방법인데, 단순히 해시되어서 나온 키 값으로 노드를 배치 시키는 방법에 비해서 노드 수를 비교적 효율적으로 삭제/ 추가할 수 있는 장점이 있다. 

 

안정 해시 예시

 

 

기존의 가장 간단한 modular hash 인 node ID = hash(key) % len(node) 를 사용한다면, 노드 갯수에 따라서 키가 전체적으로 리밸런싱되어야 하는 문제가 있지만, 안정 해시를 사용한다면 근처에 있는 노드 들의 키 값만 재배치시키면 되기 때문에 이동이 간편해진다.

 

그리고 안정 해시를 사용해서 데이터를 복제하는 방법은, 자기가 선택된 노드 부터 +1, +2 칸 옆에 있는 노드들에도 각각 데이터를 저장하게 되면 데이터 복제까지 실행시킬 수 있다. 

 

데이터 버저닝

그럼 데이터를 복제시키고 분산시켜서 저장된다고 쳤을때, 지켜야 할 것중에 하나는 데이터  일관성을 맞춰야 하는 점이다. 

만약 여러 분산 노드에서 각각 read/write 가 모두 가능한 상황이라면 사용자가 동일한 키 값을 서로 다른 노드에서 업데이트 했을때 데이터 충돌이 발생할 수 있다. 이런 경우를 방지하기 위한 방법으로 'dynamoDB' 에서는 데이터버저닝 이라는 방법을 이용하고 있다. 

 

데이터 버저닝은, 우선 데이터는 기본적으로 immutable 한 속성을 가지고 있다고 본다. 그리고 수정사항이 생길때마다 수정이 아니라, 동일한 객체가 새로 생성되면서 새로운 버전이 +1 되어서 붙게되는 개념이다. 이 개념을 도입한 것이 vector clock 인데, 데이터 버저닝을 위해 vector clock 을 이용해 충돌을 확인한다. 

 

 

위에서는 Server 가 Sx, Sy,  Sz 가 있다고 가정할 때 동일한 데이터에 대해서 같이 수정했을때의 형태를 예시로 보여주고 있다. 

vector clock 을 사용하면 각 데이터가 어떤 값을 통해 수정이 되었는지 확인할 수 있지만, 클라이언트 단에서 처리해줘야 할 것이 많아진다는 단점이 있다.