시스템 설계, 기술 면접 대비

키-값 저장소 설계 면접 퀴즈

기능이 단순한 만큼 비기능이 전부 정한다

분산 키-값 저장소 하나를 요구사항부터 끝까지 설계합니다. 데이터 100TB, 노드 300대, 쓰기 초당 10만, 읽기 초당 50만, 읽기 상위 1퍼센트 10ms, 분단 중에도 쓰기 받기라는 제약 아래에서 리더 없는 복제, 정족수, 충돌 해소, 쓰기와 읽기 경로, 파일 합치기, 장애 처리, 사본 맞추기를 다룹니다.

로그인 없이 풀어보기
16개 문제, 무료

이 설계에 주어진 요구사항

문제는 모두 이 하나의 요구사항 안에서 풉니다.

키-값 저장소 설계

분산 키-값 저장소

키로 값을 넣고 꺼내는 저장소를 여러 노드에 나눠 만듭니다. 기능이 단순한 만큼 비기능이 설계를 정합니다.

이번에 만드는 기능

  • 키로 값 넣기
  • 키로 값 꺼내기
  • 사본 유지하기
  • 노드 추가하고 제거하기

범위 밖

  • 여러 키를 묶는 트랜잭션
  • 키 범위로 훑어 읽기
  • 값 내용으로 검색하기
  • 두 번째 인덱스
  • 서버가 두 값 중 최신을 골라 주는 것

지켜야 하는 수치

데이터
100TB
노드
300대
쓰기
초당 10만
읽기
초당 50만
값 크기
평균 1KB
읽기 지연
상위 1퍼센트가 10ms 이내

전제로 주어진 것

  • 네트워크가 갈라져도 쓰기를 계속 받아야 한다
  • 노드 두 대가 동시에 죽어도 데이터가 남아야 한다
  • 성공으로 응답한 쓰기는 노드가 죽어도 사라지지 않아야 한다
  • 노드는 자주 죽고 살아난다. 재시작과 교체는 정상 상황이다
  • 읽는 쪽이 잠시 낡은 값을 보는 것은 허용한다
  • 사본은 언젠가 같아져야 한다. 언제까지인지는 정하지 않는다

학습할 핵심 개념

요구사항과 포기할 것 정하기
정족수로 조절하기
값이 갈렸을 때 고르기
쓰기 경로와 내구성
읽기 경로와 걸러내기
파일 합치기와 그 대가
잠깐 죽은 사본 다루기
사본을 다시 맞추기

핵심 개념 미리보기

키-값 저장소 설계 면접에서 꼭 나오는 개념을 미리 확인하세요

요구사항과 포기할 것 정하기

핵심

키-값 저장소는 기능이 두 개뿐입니다. 값을 넣고 꺼내는 것입니다. 기능이 단순한 만큼 설계는 비기능 요구사항이 전부 정합니다.

항목
대상분산 키-값 저장소
데이터100TB
노드300대
쓰기초당 10만
읽기초당 50만
값 크기평균 1KB
읽기 지연상위 1퍼센트가 10ms 이내
분단이 생기면쓰기를 계속 받는다
견뎌야 하는 장애노드 두 대가 동시에 죽어도 데이터가 남는다
응답한 쓰기노드가 죽어도 사라지지 않는다

기능 요구사항과 범위 밖

구분내용
이번에 만든다키로 값 넣기, 키로 값 꺼내기, 사본 유지, 노드 추가와 제거
범위 밖여러 키를 묶는 트랜잭션, 키 범위 조회, 값 내용 검색, 두 번째 인덱스, 서버가 두 값 중 최신을 골라 주는 것

범위 밖이 이 설계에서 특히 중요합니다. 여러 키를 묶는 트랜잭션을 빼면 노드 사이 합의가 필요 없어지고, 그것이 아래의 모든 선택을 가능하게 합니다. 하나만 남겨 두었다면 설계가 완전히 달라집니다.

분단 중에 쓰기를 받는다는 결정

분단이 생기면 리더가 있는 구조는 한쪽이 쓰기를 못 하고 리더가 없는 구조는 양쪽이 받는다 리더가 있으면 리더 쪽 반대쪽 리더 쪽만 쓰기를 받는다 반대쪽 사용자는 쓰기를 못 한다 리더가 없으면 한쪽 다른 쪽 양쪽이 쓰기를 받는다 같은 키에 두 값이 생길 수 있다 요구사항이 분단 중에도 쓰기를 받으라고 했다 그래서 두 값이 생기는 것을 받아들이고 나중에 정리한다 고른 것은 가용성, 낸 값은 충돌 해소라는 새 숙제다

네트워크가 갈라졌을 때 쓰기를 계속 받으려면 양쪽이 각자 받아야 합니다. 리더가 한쪽에 있으면 반대쪽 사용자는 쓰기를 할 수 없습니다.

그래서 이 요구사항은 리더가 없는 구조를 강제합니다. 어느 사본이든 쓰기를 받을 수 있고, 사본끼리 나중에 맞춥니다.

낸 값이 있습니다. 같은 키에 서로 다른 값이 생길 수 있고, 그것을 정리하는 일이 새 숙제가 됩니다. 고른 것과 낸 값을 함께 말하는 것이 이 결정을 설명하는 방법입니다.

숫자가 정하는 것

조건강제하는 것
100TB 를 300대 에키를 나눠 담아야 한다. 나누는 방법은 안정 해시 설계에서 다뤘다
쓰기 초당 10만, 값 평균 1KB초당 100MB. 제자리를 찾아 고치는 방식은 디스크가 못 따라온다
두 대 동시 사망 견디기사본이 셋 이상이어야 한다
응답한 쓰기 유실 불가응답하기 전에 디스크에 남겨야 한다
읽기 10ms값을 찾느라 파일 여러 개를 뒤지는 비용을 줄여야 한다

사본이 셋인 이유

두 대가 동시에 죽어도 데이터가 남으려면 사본이 셋 이상이어야 합니다. 둘이면 두 대가 함께 죽을 때 그 데이터가 사라집니다.

셋보다 많이 두면 저장 비용이 그만큼 늘어납니다. 100TB 에 사본 셋이면 실제로 저장하는 양은 300TB 입니다. 요구사항이 두 대까지라고 정했으므로 셋에서 멈춥니다.

이 저장소가 하지 않는 것

리더가 없으므로 "가장 최근 값" 을 아무도 확정해 주지 않습니다. 읽는 쪽이 낡은 값을 볼 수 있고, 두 값이 함께 반환될 수도 있습니다.

이 성질을 응용에 알려야 합니다. 잔액이나 재고처럼 정확한 순서가 필요한 데이터는 이 저장소에 두지 않는 편이 낫습니다. 무엇을 담을 수 있는 저장소인지가 요구사항에서 이미 정해집니다.

면접에서 이렇게 나옵니다
  • Q.키-값 저장소 설계에서 요구사항을 어떻게 정리하시겠습니까
  • Q.분단 중에도 쓰기를 받으려면 무엇을 포기해야 하나요
  • Q.사본을 몇 벌 두시겠습니까

정족수로 조절하기

핵심

사본이 셋이라고 정했습니다. 그러면 새 질문이 생깁니다. 쓸 때 몇 개가 성공하면 성공이라고 할까요. 읽을 때 몇 개에서 받아야 할까요.

이 두 숫자가 일관성과 가용성과 지연을 함께 조절하는 손잡이입니다.

숫자 두 개

사본 수를 셋이라 하고, 쓰기에 필요한 성공 수와 읽기에 필요한 응답 수를 각각 정합니다.

쓰기 성공 수 + 읽기 응답 수 > 사본 수

이 관계가 성립하면 읽을 때 받는 응답 중 최소 하나는 최신 쓰기를 받은 사본입니다. 셋 중 둘에 썼고 셋 중 둘에서 읽으면, 둘과 둘은 겹치지 않을 수 없습니다.

조합성질
쓰기 1, 읽기 1가장 빠르다. 최신 값을 만난다는 보장이 없다
쓰기 2, 읽기 2최신 값을 만난다. 한 대가 죽어도 동작한다
쓰기 3, 읽기 1읽기가 매우 빠르다. 한 대만 죽어도 쓰기가 실패한다

가용성 요구가 조합을 좁힌다

요구사항이 분단 중에도 쓰기를 받으라고 했습니다. 쓰기에 셋을 요구하면 한 대만 죽어도 쓰기가 실패하므로 그 요구를 어깁니다.

그래서 쓰기는 둘, 읽기는 둘로 둡니다. 한 대가 죽어도 양쪽 모두 동작하고 최신 값도 만납니다.

기다리는 수가 꼬리 지연을 정한다

사본 셋에 보내고 둘의 응답만 기다리면 가장 느린 응답을 기다리지 않아도 된다 사본 셋에 동시에 보낸다. 각자 응답 시간이 다르다 사본 1 2ms 사본 2 3ms 사본 3 40ms. 마침 바쁘다 둘만 기다리면 3ms 에 끝난다 셋을 다 기다리면 40ms. 가장 느린 하나가 지연을 정한다 둘을 기다리면 느린 하나를 버릴 수 있다 기다리는 수를 줄이는 것이 꼬리 지연을 줄이는 방법이다 대신 쓰기 둘, 읽기 둘이어야 최신 값을 만난다

셋에 모두 보내고 둘의 응답만 기다립니다. 그러면 마침 바쁜 사본 하나를 버릴 수 있습니다.

이것이 정족수의 덜 알려진 이득입니다. 규모가 커지면 어느 순간에도 몇 대는 느립니다. 셋을 다 기다리면 가장 느린 하나가 매 요청의 지연을 정합니다. 읽기 10ms 요구를 지키는 데 이 성질이 결정적입니다.

그래도 최신을 보장하지 못하는 경우

쓰기 둘, 읽기 둘이어도 어긋나는 상황이 남습니다.

상황무슨 일이 생기나
쓰기가 둘에 실패하고 하나만 성공실패로 응답했는데 그 하나에는 값이 남는다
두 쓰기가 동시에 다른 사본에 도달사본마다 순서가 다르게 보인다
분단 중 양쪽이 각자 둘을 채움겹치지 않는 두 정족수가 생긴다

정족수는 최신 값을 만날 확률을 높이는 장치이고, 순서를 정해 주지는 않습니다. 순서를 정하려면 리더가 필요한데 이 설계는 리더를 포기했습니다. 그래서 다음 단계에서 값이 갈렸을 때 무엇을 최신으로 볼지 정합니다.

응용마다 다르게 줄 수 있다

이 두 숫자는 요청마다 바꿀 수 있습니다. 세션 정보는 쓰기 하나로 빠르게 쓰고, 사용자 설정은 쓰기 둘로 안전하게 쓰는 식입니다.

한 저장소 안에서 데이터마다 다른 값을 주는 것이 이 방식의 큰 장점입니다. 다만 응용이 그 뜻을 알아야 하고, 모르고 쓰면 어떤 데이터는 이유 없이 낡은 값을 보게 됩니다.

면접에서 이렇게 나옵니다
  • Q.정족수를 어떻게 정하시겠습니까
  • Q.읽기 10ms 를 정족수로 어떻게 돕나요
  • Q.쓰기 둘, 읽기 둘이면 항상 최신 값을 보나요

값이 갈렸을 때 고르기

핵심

앞 단계에서 정족수가 순서를 정해 주지 않는다는 것을 봤습니다. 리더가 없으니 같은 키에 값이 둘 생길 수 있고, 이제 무엇을 최신으로 볼지 정해야 합니다.

시각으로 고르면 조용히 하나가 사라진다

두 쓰기가 같은 이전 값을 보고 시작하면 한쪽을 버릴 수 없다 둘 다 같은 값을 보고 고쳤다 장바구니 v1 사과 가: 사과, 배 나: 사과, 우유 v1 을 보고 썼다 v1 을 보고 썼다 시각으로 하나를 고르면 다른 하나가 사라진다 사용자는 담은 물건이 없어졌다고 느낀다 둘 다 v1 을 봤다는 사실이 기록되면 충돌임을 알 수 있다 알아채면 고를 수 있다. 합치거나 사용자에게 묻거나 모르면 조용히 하나를 버린다. 그것이 더 나쁘다

가장 단순한 방법은 시각이 늦은 값을 이기게 하는 것입니다. 구현이 쉽고 값이 하나로 정해집니다.

문제는 두 쓰기가 같은 이전 값을 보고 시작한 경우입니다. 위 그림에서 한 쪽은 배를, 다른 쪽은 우유를 담았습니다. 시각으로 하나를 고르면 다른 하나가 사라지고, 사용자는 담은 물건이 없어졌다고 느낍니다.

그리고 시각 자체를 믿기 어렵습니다. 노드마다 시계가 조금씩 다르므로 먼저 쓴 값이 늦은 시각을 가질 수 있습니다.

방식결과
시각이 늦은 값이 이긴다값이 하나로 정해진다. 한쪽이 조용히 사라진다
무엇을 보고 썼는지 기록한다충돌을 알아챌 수 있다. 정리 책임이 응용에 간다

무엇을 보고 썼는지 기록한다

값을 줄 때 그 값의 표시를 함께 주고, 쓸 때 그 표시를 되돌려 받습니다. 그러면 서버가 이 쓰기가 어느 값을 보고 만들어졌는지 알 수 있습니다.

읽기: 값 v1 과 함께 표시를 준다
쓰기: 새 값과 v1 표시를 함께 보낸다
서버: v1 뒤에 이미 다른 값이 있으면 충돌이다

충돌이면 두 값을 모두 보관하고 다음 읽기에서 함께 돌려줍니다. 그것을 어떻게 합칠지는 응용이 압니다. 장바구니라면 합집합을 취하면 되고, 설정값이라면 사용자에게 물어야 할 수도 있습니다.

알아채는 것이 고르는 것보다 중요하다

이 설계의 핵심은 충돌을 없애는 것이 아닙니다. 리더가 없으니 충돌은 생깁니다. 알아채지 못하는 것이 문제입니다.

상황사용자가 겪는 일
충돌을 모르고 하나를 버림담은 물건이 이유 없이 사라진다
충돌을 알고 합침둘 다 남는다
충돌을 알고 물어봄잠깐 번거롭지만 잃지 않는다

조용한 유실이 가장 나쁩니다. 사용자는 원인을 모르고, 우리도 지표에서 볼 수 없습니다.

그래도 시각으로 고르는 경우

값이 갈릴 일이 없거나, 갈려도 하나를 버려도 되는 데이터라면 시각 방식이 낫습니다.

마지막 상태만 의미 있는 값: 위치, 온도, 조회 수 갱신
이전 값을 읽고 계산해 쓰는 값: 장바구니, 잔액, 목록 편집

앞쪽은 시각으로 충분합니다. 뒤쪽에서 시각을 쓰면 사용자가 편집한 내용이 사라집니다. 데이터의 성격이 방식을 정합니다.

보관하는 값이 늘어나는 문제

충돌을 보관하면 값이 쌓입니다. 응용이 합쳐 주지 않으면 계속 늘어나므로, 합친 결과를 다시 써서 이전 것들을 정리하게 만들어야 합니다.

그리고 삭제가 어려워집니다. 값을 지우기만 하면 다른 사본에 남아 있던 옛 값이 되살아납니다. 그래서 삭제도 하나의 값으로 기록합니다. 다음 단계의 저장 구조가 이 성질과 맞물립니다.

면접에서 이렇게 나옵니다
  • Q.같은 키에 두 값이 생기면 무엇을 최신으로 보시겠습니까
  • Q.시각이 늦은 값이 이기게 하면 무엇이 문제인가요
  • Q.시각 방식을 써도 되는 데이터는 무엇인가요

더 많은 개념과 문제는 가입 후 이용할 수 있어요

먼저 5문제 맛보기

키-값 저장소 설계 면접 빈출 질문

실제 면접에서 자주 나오는 질문들입니다

Q.

키-값 저장소 설계에서 요구사항을 어떻게 정리하시겠습니까

요구사항과 포기할 것 정하기 개념 정리 보기
Q.

분단 중에도 쓰기를 받으려면 무엇을 포기해야 하나요

요구사항과 포기할 것 정하기 개념 정리 보기
Q.

이 저장소에 담기 어려운 데이터는 무엇인가요

요구사항과 포기할 것 정하기 개념 정리 보기
Q.

정족수를 어떻게 정하시겠습니까

정족수로 조절하기 개념 정리 보기
Q.

읽기 10ms 를 정족수로 어떻게 돕나요

정족수로 조절하기 개념 정리 보기
Q.

쓰기 둘, 읽기 둘이면 항상 최신 값을 보나요

정족수로 조절하기 개념 정리 보기
Q.

데이터마다 정족수를 다르게 줄 수 있나요

정족수로 조절하기 개념 정리 보기

이런 점이 좋아요

가용성을 고른 대가를 끝까지 따라가는 훈련

급하지 않은 일과 급한 일의 자원 다툼을 보는 눈

약속하지 않는 것을 명확히 적는 습관

지금 바로 시작하세요

무료로 키-값 저장소 설계 퀴즈를 풀고, AI 오답 분석으로 실력을 키우세요.